pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.web.socket</groupId>
<artifactId>web-socket</artifactId>
<version>1.0.0</version>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.7.8</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
项目结构
websocket主要注解类:
@ServerEndpoint("/im/{username}")
服务端点(/im/{username})
ws://127.0.0.1:8080/im/test
@Component 将当前类加入容器中加上该注解之后不要方法上使用@PathVariable 参数进行接收否则失败
@Data
@Slf4j
@ServerEndpoint("/im/{username}")
@Component
public class WebSocketServerEndpont {
private static final ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();
private Session session;
private String username;
@OnOpen
public void onOpen(Session session) {
Map<String, String> pathParameters = session.getPathParameters();
String username = pathParameters.get("username");
this.username = username;
this.session = session;
sessionMap.put(username, session);
log.info("--------用户:{}登录成功,在线人数:{}", username, sessionMap.size());
}
@OnClose
public void onClose() {
if (sessionMap.containsKey(username)) {
sessionMap.remove(username);
}
log.info("--------用户:{}退出登录,在线人数:{}", username, sessionMap.size());
}
@OnMessage
public void onMessage(Session session, String message) {
String from = getUserNameBySession(session);
log.info("--------用户:{}发送信息:{}", from, message);
sendMessage(message);
}
private void sendMessage(String message) {
String from = getUserNameBySession(session);
sessionMap.forEach((k, v) -> {
if (!k.equals(from)) {
v.getAsyncRemote().sendText(message);
}
});
}
@OnError
public void onError(Session session, Throwable throwable) {
}
private String getUserNameBySession(Session session) {
return session.getPathParameters().get("username");
}
}
启动:使用websocket在线工具: ws://127.0.0.1:8080/im/test,开启两个浏览器即可实现聊天
关于部署到linux 访问不到的问题:
首先ssl 证书要配置好。
nginx配置:
upstream sockets { server 127.0.0.1:8080 max_fails=3 fail_timeout=10s; } server { listen 443 ssl; server_name 域名; #调整成自己的证书即可,重点重点重点 ssl_certificate /etc/nginx/cert/ssl.pem; ssl_certificate_key /etc/nginx/cert/ssl.key; ssl_session_timeout 5m; #通过location进行处理,重点重点重点 location / { proxy_pass http://sockets; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } error_page 404 /404.html; }
服务地址要使用:wss://域名/im/test