WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。WebSocket相比使用轮询的方式更加节省资源。
适用场景:弹幕、定时系统信息、聊天等
1、POM依赖导入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、配置ServerEndpointExporter
@Configuration
@EnableWebSocket
@Service
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3、然后进行简单的连接、断开、消息接收等操作,此处只是简单展示,可根据实际业务功能扩展
@Component
@ServerEndpoint(value = "/webSocket/{account}")
@Slf4j
public class WebSocket{
private static int loginCount = 0;
private static Map<String, WebSocket> users = new ConcurrentHashMap<String, WebSocket>();
private Session session;
private String account;
// 收到消息触发事件
@OnMessage
public void onMessage(String message, Session session) throws IOException, InterruptedException {
//JSON数据
log.info("onMessage:{}",message);
Map<String,String> map = JSON.parseObject(message, HashMap.class);
//接收人
String to = map.get("to");
//内容
String info = map.get("info");
if (to.equals("All")){
sendMessageAll("ALL:"+info);
}else{
sendMessageTo(info,to);
}
}
// 打开连接触发事件
@OnOpen
public void onOpen(@PathParam("account") String account, Session session, EndpointConfig config) {
log.info("onOpen:{}",account);
this.account = account;
this.session = session;
//添加登录用户数量
addLoginCount();
users.put(account, this);
log.info("当前在线人数:"+loginCount);
log.info("已连接:"+account);
}
// 关闭连接触发事件
@OnClose
public void onClose(Session session, CloseReason closeReason) {
log.info("onClose");
users.remove(account);
//减少断开连接的用户
reduceLoginCount();
}
// 传输消息错误触发事件
@OnError
public void one rror(Throwable error) {
log.info("onError:{}",error.getMessage());
}
public void sendMessageTo(String message, String To) throws IOException {
for (WebSocket item : users.values()) {
if (item.account.equals(To) )
item.session.getAsyncRemote().sendText(message);
}
}
public void sendMessageAll(String message) throws IOException {
for (WebSocket item : users.values()) {
item.session.getAsyncRemote().sendText(message);
}
}
public static synchronized void addLoginCount() {
WebSocket.loginCount++;
}
public static synchronized void reduceLoginCount() {
WebSocket.loginCount--;
}
public static synchronized Map<String, WebSocket> getUsers() {
return users;
}
}
- onOpen:前端连接到WebSocket时触发,可用作记录用户信息初始化。
- onClose:断开WebSocket连接时,清除用户数据。
- onMessage:收到消息时,进行处理。
- onError:出现异常时的处理。
效果图:
admin账户:
test1账户:
日志记录:
测试地址:http://www.websocket-test.com/
文章仅用学习记录,有不对的地方请各位大佬指导,毕竟也是头回写。