1、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、创建SocketUtils,用于websocket服务的调用,代码如下
/**
* websocket 工具类
*
* @author fxl
* @date 2018/12/11
*/
@ServerEndpoint(value = "/socketServer/{userid}", encoders = {WebSocketEncoder.class})
@Component
public class SocketUtils {
private Session session;
private static Map<String, Session> sessionPool = new HashMap<>();
private static Map<String, String> sessionIds = new HashMap<>();
/**
* 用户连接时触发
*
* @param session 回话
* @param userid 用户id
*/
@OnOpen
public void open(Session session, @PathParam(value = "userid") String userid) {
this.session = session;
sessionPool.put(userid, session);
sessionIds.put(session.getId(), userid);
}
/**
* 收到信息时触发
*
* @param message 消息内容
*/
@OnMessage
public void onMessage(String message) {
if (("ping").equals(message)) {
sendMessage("pong", sessionIds.get(session.getId()));
} else {
sendMessage(sessionIds.get(session.getId()) + "<--" + message, "niezhiliang9595");
}
}
/**
* 连接关闭触发
*/
@OnClose
public void onClose() {
sessionPool.remove(sessionIds.get(session.getId()));
sessionIds.remove(session.getId());
}
/**
* 发生错误时触发
*
* @param session 回话
* @param error 错误
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
/**
* 信息发送的方法,发送文本
*
* @param message 消息内容
* @param userId 用户id
*/
private static void sendMessage(String message, String userId) {
Session s = sessionPool.get(userId);
if (s != null) {
try {
s.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 信息发送的方法,发送实体类
*
* @param object 通知实体类
* @param userId 用户id
*/
private static void sendMessage(Object object, String userId) throws IOException, EncodeException {
Session s = sessionPool.get(userId);
if (s != null) {
s.getBasicRemote().sendObject(object);
}
}
/**
* 获取当前连接数
*
* @return int 连接数
*/
private static int getOnlineNum() {
if (sessionIds.values().contains("niezhiliang9595")) {
return sessionPool.size() - 1;
}
return sessionPool.size();
}
/**
* 获取在线用户id以逗号隔开
*
* @return String 用户id串
*/
private static String getOnlineUsers() {
StringBuffer users = new StringBuffer();
// niezhiliang9595是服务端自己的连接,不能算在线人数
for (String key : sessionIds.keySet()) {
if (!"niezhiliang9595".equals(sessionIds.get(key))) {
users.append(sessionIds.get(key) + ",");
}
}
return users.toString();
}
/**
* 信息群发,发送给所有人
*
* @param object 消息实体类
*/
public static void sendAll(Object object) throws IOException, EncodeException {
for (String key : sessionIds.keySet()) {
if (!"niezhiliang9595".equals(sessionIds.get(key))) {
sendMessage(object, sessionIds.get(key));
}
}
}
/**
* 多个人发送给指定的几个用户
*
* @param object 实体类
* @param idsArray 用户id数组
*/
public static void sendMany(Object object, String[] idsArray) throws IOException, EncodeException {
for (String userId : idsArray) {
sendMessage(object, userId);
}
}
/**
* 多个人发送给指定的几个用户
*
* @param message 消息字符串
* @param idsArray 用户id数组
*/
public static void sendMany(String message, String[] idsArray) {
for (String userId : idsArray) {
sendMessage(message, userId);
}
}
}
3、添加websocket配置类
/**
* websocket配置类
*
* @author Zhy
* @date 2018/12/11
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
4、添加实体类编码配置类,该类用于配置使用实体类作为消息内容时的编码,即SocketUtils中的sendMany(Object object,String[] idsArray)时会用到,该配置类代码如下:
/**
* WebSocket传递实体编码
*
* @author fxl
* @date 2018/12/13
*/
public class WebSocketEncoder implements Encoder.Text<JSONObject> {
@Override
public String encode(JSONObject notify) {
try {
return notify.toJSONString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
public void init(EndpointConfig endpointConfig) {
}
@Override
public void destroy() {
}
}