ssm实现webSocket
一、引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
二、编写websocketController
package com.chuji.controller;
import com.chuji.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Author: 欧阳锋
* @Description: websocket 接口
* @Date: Created in 16:25 2021/3/30
* @Modified By:
*/
@ServerEndpoint("/websocket/{myWebsocket}")
@Component
@Slf4j
public class WebsocketController {
//用以下代码替换注释掉的代码,问题解决
private static UserService userService;
@Autowired
public void setPlanmecaScreenService(UserService userService){
WebsocketController.userService = userService;
}
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
private static final Logger logger = LoggerFactory.getLogger(WebsocketController.class);
public static Map<String, List<Session>> clients = new ConcurrentHashMap<String, List<Session>>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
private static ConcurrentHashMap<String, WebsocketController> webSocketSet = new ConcurrentHashMap<String, WebsocketController>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session WebSocketsession;
String myWebsocket = "";
/**
* 连接建立成功调用的方法
* @param myWebsocket
* @param session
*/
@OnOpen
public void onOpen(@PathParam("myWebsocket") String myWebsocket, Session session){
System.out.println(myWebsocket);
//接收到发送消息的人员编号
myWebsocket = myWebsocket;
this.WebSocketsession = session;
this.session = session;
List<Session> sessions = null;
if(clients.get(myWebsocket) != null){
sessions = clients.get(myWebsocket);
sessions.add(session);
}else{
sessions = new ArrayList<Session>();
sessions.add(session);
}
clients.put(myWebsocket, sessions);
//加入map中
webSocketSet.put(myWebsocket, this);
addOnlineCount();//在线数加1
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息时触发
* @param myWebsocket
* @param message
* @return
*/
@OnMessage
public void onMessage(@PathParam("myWebsocket") String myWebsocket, String message) {
System.out.println("来自客户端的消息:" + message);
sendMessage(myWebsocket,message);
// return "Got your message ("+ message +").Thanks !";
}
/**
* 异常时触发
* @param myWebsocket
* @param throwable
*/
@OnError
public void onError(@PathParam("myWebsocket") String myWebsocket, Throwable throwable) {
logger.info("Websocket Connection Exception:" + myWebsocket);
logger.info(throwable.getMessage(), throwable);
clients.remove(myWebsocket);
}
/**
* 关闭连接时触发
* @param myWebsocket
*/
@OnClose
public void onClose(@PathParam("myWebsocket") String myWebsocket) {
logger.info("Websocket Close Connection:" + myWebsocket);
subOnlineCount();
clients.remove(myWebsocket);
}
/**
* 将数据传回客户端
* 异步的方式
* @param myWebsocket
* @param message
*/
public static void broadcast(String myWebsocket, String message) {
if (clients.containsKey(myWebsocket)) {
// clients.get(myWebsocket).getAsyncRemote().sendText(message);
List<Session> sessions = clients.get(myWebsocket);
for(Session sess : sessions){
sess.getAsyncRemote().sendText(message);
}
} else {
throw new NullPointerException("[" + myWebsocket +"]Connection does not exist");
}
}
public static synchronized int getOnlineCount() {
//返回在线人数
return onlineCount;
}
public static synchronized void addOnlineCount() {
//在线人数+1
WebsocketController.onlineCount++;
}
public static synchronized void subOnlineCount() {
//在线人数-1
WebsocketController.onlineCount--;
}
public void sendMessage(String myWebsocket, String message) {
synchronized(webSocketSet.get(myWebsocket)) {
//根據手機號查詢用戶信息 並轉成json
// UserPO user = userService.getUserByPhone(myWebsocket);
// CommonResponse<UserPO> common = new CommonResponse<UserPO>(ResponseTypeEnums.SUCCESS, null, null, user);
// String json= JSON.toJSONString(common);
List<Session> sessions = clients.get(myWebsocket);
for(Session sess : sessions){
try {
// sess.getBasicRemote().sendText(json);
sess.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
三、事实上完成了第二步就能基本连接了,但是如果想要后端发送消息到前端的话,需要调用,所以创建WebSocketService
package com.chuji.service;
/**
* @Author: 欧阳锋
* @Description: webSocket service
* @Date: Created in 10:20 2021/3/31
* @Modified By:
*/
public interface WebSocketService {
void sendMessage(String userPhone,String type);
}
package com.chuji.service.impl;
import com.alibaba.fastjson.JSON;
import com.chuji.controller.WebsocketController;
import com.chuji.dao.UserPOMapper;
import com.chuji.model.PO.UserPO;
import com.chuji.service.WebSocketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Author: 欧阳锋
* @Description: webSocket service
* @Date: Created in 10:21 2021/3/31
* @Modified By:
*/
@Service
public class WebSocketServiceImpl implements WebSocketService {
@Autowired
private UserPOMapper userPOMapper;
@Autowired
private WebsocketController webSocket;
@Override
public void sendMessage(String userPhone, String type) {
//獲取修改後的用戶信息
UserPO userPO = new UserPO();
userPO.setUserPhone(userPhone);
userPO.setUserState((byte)1);
//像用戶端發送信息
UserPO user = userPOMapper.getUserLoginByPhone(userPO);
if("updatePassword".equals(type)){
user.setUserPwd("updatePassword");
}else{
user.setUserPwd("");
}
webSocket.onMessage(userPhone, JSON.toJSONString(user));
}
}
四、通过service调用webSocket
//調用websocket發送數據到前台
wsService.sendMessage(userPhone,"updatePassword");
写好之后可以用在线websocket测试进行调试
这样就大功告成!!!