网易首页 > 网易号 > 正文 申请入驻

websocket的自定义使用

0
分享至

  • 1.添加依赖

  • 2.编辑WebSocketConfig,

  • 3.编写WebSocketHandlerInterceptor

  • 4.编写MyWebSocketHandler

    • 使用

  • 5.自定义解码器

    • 使用

很多时候发消息,需要对指定的用户发送,某个部门,每个小组,部分通知等,这时就需要自定义websocket,以下就是关于自定义websocket的基本步骤

1.添加依赖

org.springframework
spring-messaging
4.1.7.RELEASE

org.springframework
spring-websocket
4.1.7.RELEASE

javax.websocket
javax.websocket-api
1.0
provided

2.编辑WebSocketConfig,

根据spring文档,编写websocketConfig,这里可参看文档,xml配置和使用注解两种方式,我选择注解方式

registerWebSocketHandlers:这个方法是向spring容器注册一个handler地址,我把他理解成requestMapping(也可以理解为@ServerEndpoint("/webSocket"))

addInterceptors:拦截器,当建立websocket连接的时候,我们可以通过继承spring的HttpSessionHandshakeInterceptor来搞事情。

setAllowedOrigins:跨域设置,表示所有域名都可以,不限制, 域包括ip:port, 指定可以是任意的域名,不加的话默认localhost+本服务端口

withSockJS:这个是应对浏览器不支持websocket协议的时候降级为轮询的处理。

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(webSocketHandler(), "/websocket/socketServer")
.addInterceptors(new WebSocketHandlerInterceptor()).setAllowedOrigins("*");

registry.addHandler(webSocketHandler(), "/sockjs/socketServer").setAllowedOrigins("http://localhost:28180")
.addInterceptors(new WebSocketHandlerInterceptor()).withSockJS();
}
@Bean
public TextWebSocketHandler webSocketHandler() {
return new WebSocketHandler();
}
}

3.编写WebSocketHandlerInterceptor

这个是创建websocket连接是的拦截器,记录建立连接的用户的session以便根据不同session来通信

public class WebSocketHandlerInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map attributes) throws Exception {
System.out.println("Before Handshake");
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession(false);
if (session != null) {
//使用userName区分WebSocketHandler,以便定向发送消息
String userName = (String) session.getAttribute("SESSION_USERNAME"); //一般直接保存user实体
if (userName != null) {
attributes.put("WEBSOCKET_USERID", userName);
}

}
}
return super.beforeHandshake(request, response, wsHandler, attributes);

}

@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}

}

4.编写MyWebSocketHandler @Configuration
public class MyWebSocketHandler extends TextWebSocketHandler {
//Map来存储WebSocketSession,key用USER_ID 即在线用户列表
private static ConcurrentHashMap users = new ConcurrentHashMap<>();
//用户标识
private static final String USER_ID = "WEBSOCKET_USERID"; //对应监听器从的key

public MYWebSocketHandler() {
}

/**
* 连接成功时候,会触发页面上onopen方法
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("成功建立websocket连接!");
String userId = session.getId();
users.put(userId, session);
System.out.println("当前线上用户数量:" + users.size());

//这块会实现自己业务,比如,当用户登录后,会把离线消息推送给用户
//TextMessage returnMessage = new TextMessage("成功建立socket连接,你将收到的离线");
//session.sendMessage(returnMessage);
}

/**
* 关闭连接时触发
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
String userId = (String) session.getAttributes().get(USER_ID);
System.out.println("用户" + userId + "已退出!");
users.remove(userId);
System.out.println("剩余在线用户" + users.size());
}

/**
* js调用websocket.send时候,会调用该方法
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
/**
* 收到消息,自定义处理机制,实现业务
*/
System.out.println("服务器收到消息:" + message);
if (message.getPayload().startsWith("#anyone#")) { //单发某人
sendMessageToUser((String) session.getAttributes().get(USER_ID), new TextMessage("服务器单发:" + message.getPayload()));
} else if (message.getPayload().startsWith("#everyone#")) {
sendMessageToUsers(new TextMessage("服务器群发:" + message.getPayload()));
} else {

}

}

@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
if (session.isOpen()) {
session.close();
}
System.out.println("传输出现异常,关闭websocket连接... ");
String userId = (String) session.getAttributes().get(USER_ID);
users.remove(userId);
}

@Override
public boolean supportsPartialMessages() {
return false;
}

/**
* 给某个用户发送消息
*
* @param userId
* @param message
*/
public void sendMessageToUser(String userId, TextMessage message) {
for (String id : users.keySet()) {
if (id.equals(userId)) {
try {
if (users.get(id).isOpen()) {
users.get(id).sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}

/**
* 给所有在线用户发送消息
*
* @param message
*/
public void sendMessageToUsers(TextMessage message) {
for (String userId : users.keySet()) {
try {
if (users.get(userId).isOpen()) {
users.get(userId).sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

使用 @Autowired
MyWebSocketHandler webSocket;

5.自定义解码器 public class WebSocketCustomEncoding implements Encoder.Text {
@Override
public String encode(Map user) {
assert user != null;
return JSON.toJSONString(user);
}

@Override
public void init(EndpointConfig endpointConfig) {

}

@Override
public void destroy() {

}
}
使用 @ServerEndpoint(value = "/webSocketService", encoders = {ImageEncoder.class})

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
热浪席卷欧洲多国屡破高温纪录,在英华人:没有空调晚上无法入睡,风扇价格翻3倍还无现货

热浪席卷欧洲多国屡破高温纪录,在英华人:没有空调晚上无法入睡,风扇价格翻3倍还无现货

极目新闻
2026-06-27 11:59:02
国足土帅最大希望!郑智豪取13场不败:1数据中超只有他做到

国足土帅最大希望!郑智豪取13场不败:1数据中超只有他做到

邱泽云
2026-06-28 22:33:08
医疗界最大的黑色幽默来了:保安不够,医生来凑?三甲医院这波 "降本增效",我看笑了,也看哭了!

医疗界最大的黑色幽默来了:保安不够,医生来凑?三甲医院这波 "降本增效",我看笑了,也看哭了!

医客
2026-06-28 12:14:18
WTT美国大满贯女单签表:陈熠对阵韩莹,覃予萱迎战莎宾-温特

WTT美国大满贯女单签表:陈熠对阵韩莹,覃予萱迎战莎宾-温特

懂球帝
2026-06-28 15:47:15
WTT大满贯:国乒全军覆没,头号种子爆冷出局

WTT大满贯:国乒全军覆没,头号种子爆冷出局

郭蛹包工头
2026-06-28 12:58:37
三大舰队或无法满足需求?一旦组建第四舰队,驻地在哪最为精妙?

三大舰队或无法满足需求?一旦组建第四舰队,驻地在哪最为精妙?

地球记
2026-06-29 01:34:26
杨少华之死:杨家儿子榨取杨老价值?很多人已理解不了老一辈精神

杨少华之死:杨家儿子榨取杨老价值?很多人已理解不了老一辈精神

雍亲王府
2026-06-28 07:25:07
女儿估分710,老公到处喊着清华九月见,放榜那天一家人盯着屏幕沉默了十分钟

女儿估分710,老公到处喊着清华九月见,放榜那天一家人盯着屏幕沉默了十分钟

热心市民小黄
2026-06-28 20:41:58
李良辉:原新疆军区司令,58岁升为中将,2000年军车爆炸后被免职

李良辉:原新疆军区司令,58岁升为中将,2000年军车爆炸后被免职

战域笔墨
2026-06-28 15:00:58
说实话,50岁还有这状态,真是岁月不败美人,风韵犹存!

说实话,50岁还有这状态,真是岁月不败美人,风韵犹存!

东方不败然多多
2026-06-28 15:28:19
医生告诫:一旦确诊颈动脉斑块,6种食物必须戒掉,避免斑块增大

医生告诫:一旦确诊颈动脉斑块,6种食物必须戒掉,避免斑块增大

荆医生科普
2026-06-25 21:40:07
徐帆回应离婚9个月后,冯小刚再陷争议,养女徐朵成导火索

徐帆回应离婚9个月后,冯小刚再陷争议,养女徐朵成导火索

枯蝶
2026-05-21 22:22:13
“一大早天塌了……”最近大量宝马车主被一个弹窗吓懵,官方紧急回应:系统误报

“一大早天塌了……”最近大量宝马车主被一个弹窗吓懵,官方紧急回应:系统误报

极目新闻
2026-06-26 16:27:14
中美局势可能会发生重大反转,最先超过美国的竟不是经济!

中美局势可能会发生重大反转,最先超过美国的竟不是经济!

音乐时光的娱乐
2026-06-29 03:31:54
你敢信吗?一个美国安插在中国潜伏了多年的间谍头子,居然是他

你敢信吗?一个美国安插在中国潜伏了多年的间谍头子,居然是他

无情有思ss
2026-06-06 02:21:10
谢霆锋西安开唱前低调打卡油泼面馆,老板称当时根本没认出来,此前他和王菲一同现身咸阳机场

谢霆锋西安开唱前低调打卡油泼面馆,老板称当时根本没认出来,此前他和王菲一同现身咸阳机场

极目新闻
2026-06-27 15:21:39
如果在家突发心梗,黄金6分钟自救法,快了解,关键时刻可自救

如果在家突发心梗,黄金6分钟自救法,快了解,关键时刻可自救

健康科普365
2026-01-20 16:05:03
成本20卖3000,555亿身家的山东美女富豪,凭什么收割爱美女性?

成本20卖3000,555亿身家的山东美女富豪,凭什么收割爱美女性?

青眼财经
2026-06-27 08:00:24
甲骨文6380亿美元AI订单悬了?过半客户集中OpenAI,股价暴跌57%后仅13.6倍市盈率

甲骨文6380亿美元AI订单悬了?过半客户集中OpenAI,股价暴跌57%后仅13.6倍市盈率

碳基打工人
2026-06-29 00:10:18
我爸工资2w全部上交我妈,他动手术要60w,我妈扑通一声跪地下了

我爸工资2w全部上交我妈,他动手术要60w,我妈扑通一声跪地下了

黑猫故事所
2026-06-25 20:26:46
2026-06-29 05:31:00
IT小咖
IT小咖
专注Java技术分享,面试题总结。一起聊人生,一起学习进步
13文章数 2关注度
往期回顾 全部

科技要闻

DeepSeek最新论文:如何让大模型跑得更快

头条要闻

四川宜宾市高县发生5.5级地震 震中距宜宾28公里

头条要闻

四川宜宾市高县发生5.5级地震 震中距宜宾28公里

体育要闻

两周飞5万公里!因凡蒂诺遭环保人士猛批

娱乐要闻

曾沛慈拿下《乘风2026》年度总冠军

财经要闻

省钱,我只服梁文锋

汽车要闻

搭载华为乾崑六件套 东风奕派M8预售19.98万起

态度原创

本地
亲子
家居
公开课
军事航空

本地新闻

世界杯球迷节:比球赛更好玩的派对

亲子要闻

2岁孩子触电心脏骤停,这些问题一定要警惕!

家居要闻

绿意盎然 自然之境

公开课

李玫瑾:为什么性格比能力更重要?

军事要闻

特朗普又发文威胁:伊朗将不复存在

无障碍浏览 进入关怀版