java后端实现Websocket服务,供前端建立连接
一、搭建一个简单的springBoot项目,导入以下jar包<dependency><groupId>javax</groupId><artifactId>javaee-api</artifactId><version>7.0</version><scope>provided</scope>
·
一、搭建一个简单的springBoot项目,导入以下jar包
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
二,编写WebSocket服务
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* 开启WebSocket支持
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
* 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
*/
@ServerEndpoint("/notice/{userId}")
@Component
@Slf4j
public class NoticeWebsocket {
//记录连接的客户端
public static Map<String, Session> clients = new ConcurrentHashMap<>();
/**
* userId关联sid(解决同一用户id,在多个web端连接的问题)
*/
public static Map<String, Set<String>> conns = new ConcurrentHashMap<>();
private String sid = null;
private String userId;
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
String tempSid = session.getId();
this.sid = tempSid;
this.userId = userId;
clients.put(tempSid, session);
Set<String> clientSet = conns.get(userId);
if (clientSet==null){
clientSet = new HashSet<>();
conns.put(userId,clientSet);
}
clientSet.add(tempSid);
log.error("DeviceWebsocket---onOpen===>id:{}--{}--连接数:{}--在线数:{}--当前设备连接数:{}", userId, tempSid, clients.size(), conns.size(), conns.get(userId).size());
}
@OnClose
public void onClose(Session session, @PathParam("userId") String userId) {
String tempSid = session.getId();
//log.info(this.sid + "连接断开!");
closeSession(tempSid, userId);
}
public void closeSession(String sid, String userId){
Session s = clients.remove(sid);
if (s!=null){
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Set<String> clientSet = conns.get(userId);
if (clientSet!=null){
clientSet.remove(sid);
}
int currentConnectCount = clientSet.size();
if(clientSet!=null && clientSet.size()==0){
conns.remove(userId);
currentConnectCount = 0;
}
log.error("DeviceWebsocket---onClose===>id:--{}--{}--连接数:{}--在线数:{}--当前设备连接数:{}", userId, sid, clients.size(), conns.size(), currentConnectCount);
//log.error("在线人数===="+clients.size());
}
public static void sendMessage(String noticeType){
NoticeWebsocketResp noticeWebsocketResp = new NoticeWebsocketResp();
noticeWebsocketResp.setNoticeType(noticeType);
sendMessage(noticeWebsocketResp);
}
/**
* 发送给所有用户
* @param noticeWebsocketResp
*/
public static void sendMessage(NoticeWebsocketResp noticeWebsocketResp){
String message = JSONObject.toJSONString(noticeWebsocketResp);
for (Session session1 : NoticeWebsocket.clients.values()) {
try {
session1.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 根据用户id发送给某一个用户
* **/
public static void sendMessageByUserId(String userId, NoticeWebsocketResp noticeWebsocketResp) {
if (!StringUtils.isEmpty(userId)) {
String message = JSONObject.toJSONString(noticeWebsocketResp);
Set<String> clientSet = conns.get(userId);
if (clientSet != null) {
Iterator<String> iterator = clientSet.iterator();
while (iterator.hasNext()) {
String sid = iterator.next();
Session session = clients.get(sid);
if (session != null) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}else {
iterator.remove();;
}
}
}
}
}
@OnError
public void onError(Throwable error) {
error.printStackTrace();
}
}
三、构建一个返回对象
@Data
@ApiModel("ws通知返回对象")
public class NoticeWebsocketResp<T> {
@ApiModelProperty(value = "通知类型")
private String noticeType;
@ApiModelProperty(value = "通知内容")
private T noticeInfo;
}
四、测试结果(这里我用的是在线的webSocket工具:在线websocket测试-在线工具-postjson)
NoticeWebsocket---onOpen===>id:666666--CXD6bnRwNCxDi-AD-UjwIRpXNIVupeV2KYTCrf8f--连接数:1--在线数:1--当前设备连接数:1
NoticeWebsocket---onOpen===>id:666666--WG4tDa22d50iCChcMb5XQ0yeuob7h6KyoywJs_5h--连接数:2--在线数:1--当前设备连接数:2
NoticeWebsocket---onOpen===>id:666666--109ZAVijoO0_eslj6V0LdzaROGRUPaoG7ctT6UsA--连接数:3--在线数:1--当前设备连接数:3
NoticeWebsocket---onOpen===>id:777777--p2TgD2r9u4IQj7gOXbH9yBvlSyNJ4hYszE3QGr6S--连接数:4--在线数:2--当前设备连接数:1
NoticeWebsocket---onClose===>id:--666666--WG4tDa22d50iCChcMb5XQ0yeuob7h6KyoywJs_5h--连接数:3--在线数:2--当前设备连接数:2
更多推荐
已为社区贡献3条内容
所有评论(0)