言成言成啊 | Kit Chen's Blog

WebSocket实现简易聊天室

发布于2021-07-29 20:44:52,更新于2021-08-05 23:46:15,标签:java open socket  文章会持续修订,转载请注明来源地址:https://meethigher.top/blog

参考文章

先放上一个坑的解决办法吧。

我用Java开启一个WebSocket服务器,通过localhost是可以连接的,通过127也可以,但是换成局域网ip之后,就连不上了。

这个坑,大概花了我一周的时间,原因很简单。比方说我的宽带、wlan、vmware虚拟机,都有一个局域网ip,如下图。

通过http,不管走哪一个局域网ip,都能访问到服务器上的页面,但是websocket不一样,websocket服务器启动之后,只能绑定一个ip,至于绑定的哪一个,不知道。所以如果想要用指定的局域网ip进行测试时,可以把其他的网络适配器禁用。

WebSocketConfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
/**
* 注册STOMP端点,将每个端点映射到一个特定的URL,并(可选地)启用和配置SockJS回退选项。
*
* @param registry
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//注册websocket站点、允许跨域、允许不支持ws端使用SockJs。http://localhost:8080/ws
registry.addEndpoint("/ws")
.setAllowedOriginPatterns("*")
.withSockJS();
}

/**
* 配置与处理从WebSocket客户端接收和发送到WebSocket客户端的消息相关的选项。
*
* @param registry
*/
@Override
public void configureWebSocketTransport(WebSocketTransportRegistration registry) {
}

/**
* 配置{@link org.springframework.messaging.MessageChannel}用于从WebSocket客户端传入消息。
* 默认情况下,通道由大小为1的线程池支持。建议为生产使用定制线程池设置。
*
* @param registration
*/
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
}

/**
* 配置{@link org.springframework.messaging.MessageChannel}用于向WebSocket客户端出站消息。
* 默认情况下,通道由大小为1的线程池支持。建议为生产使用定制线程池设置。
*
* @param registration
*/
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {

}

/**
* 添加解析器以支持自定义控制器方法参数类型。这并不覆盖解析处理程序方法参数的内置支持。
* 要自定义参数解析的内置支持,请直接配置{@code SimpAnnotationMethodMessageHandler}。
*
* @param argumentResolvers
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {

}

/**
* 添加处理程序以支持自定义控制器方法返回值类型。<p>使用此选项不会覆盖处理返回值的内置支持。
* 要自定义处理返回值的内置支持,请直接配置{@code SimpAnnotationMethodMessageHandler}。
*
* @param returnValueHandlers
*/
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {

}

/**
* 配置消息转换器,以便在提取带注释的方法中的消息有效负载和发送消息时使用(例如通过“代理”SimpMessagingTemplate)。
* 提供的列表(最初为空)可用于添加消息转换器,而布尔返回值用于确定是否也应添加默认消息。
*
* @param messageConverters
* @return
*/
@Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
return false;
}

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
//全局使用的消息前缀
registry.setApplicationDestinationPrefixes("/");
//订阅broker的名称
registry.enableSimpleBroker("/chatRoom");
}
}

MessageController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Controller
public class MessageController {
private static final String ONLINE_USERS = "onlineUsers";
private static List<String> list = new LinkedList<>();

@MessageMapping("/sendMessage")
@SendTo("/chatRoom")
public Message sendMessage(@RequestBody Message message) {
return message;
}

@MessageMapping("/addUser")
@SendTo("/chatRoom")
public Message addUser(@RequestBody Message message, SimpMessageHeaderAccessor headerAccessor) {
//添加到全局Map里面
list.add(message.getUsername());
System.out.println(list.size());
return message;
}

@MessageMapping("/delUser")
@SendTo("/chatRoom")
public Message delUser(@RequestBody Message message) {
//删除用户
list.remove(message.getUsername());
System.out.println(list.size());
return message;
}

@MessageMapping("/getUsers")
@SendTo("/chatRoom")
public Integer getUsers() {
//获取在线的人数
return list.size();
}
}

WebSocketEventListener

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Component
public class WebSocketEventListener {
private static final Logger log = LoggerFactory.getLogger(WebSocketEventListener.class);

@Autowired
private SimpMessageSendingOperations simpMessageTemplate;

@EventListener
public void connect(SessionConnectEvent event) {
log.info("正在连接...");
}

@EventListener
public void connected(SessionConnectedEvent event) {
log.info("已连接上!");
}

@EventListener
public void disconnected(SessionDisconnectEvent event) {
log.info("关闭连接!");
}
}

运行结果,还存在一点问题,需要进行修改。

发布:2021-07-29 20:44:52
修改:2021-08-05 23:46:15
链接:https://meethigher.top/blog/2021/websocket-chat/
标签:java open socket 
付款码 打赏 分享
Shift+Ctrl+1 可控制工具栏