springboot java websocket ws 快速入门
程序员文章站
2022-04-28 11:59:28
...
学而不思则罔,思而不学则殆。
一、背景介绍
java 大部分都是在做服务端,主要的流程也都是客户端发起一个http请求,服务端接收请求,然后响应数据
如果这个时候服务端想往客户端发送数据,比较常见的就是有
- 轮序: 也就是客户端一直往服务端请求获取要的数据,这样服务端压力大
- 长连接: 用 iframe 的方式 保持一个持久的连接,对服务端压力也大.
- webSocket: 这个就是这篇文章要讲的,以TCP的方式 建立连接之后就可以双向通信了
二、最佳实践
2.1 引入依赖
<!-- spring boot 的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- websocket 的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.2 启动类上添加注解 @EnableWebSocket 和注入ServerEndpointExporter
@SpringBootApplication
@EnableWebSocket
@MapperScan("com.example.demo.dao")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
/**
* 初始化Bean,它会自动注册使用了 @ServerEndpoint 注解声明的 WebSocket endpoint
* @return
*/
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
2.3 编写服务端实例
package com.example.demo.websocket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Classname WebSocketTest
* @Description webSocket 测试类
* @Date 2020/11/27 13:23
* @Created by dongzhiwei
*/
@ServerEndpoint(value="/websocket/{id}")
@Slf4j
@Component
public class WebSocketTest {
private static int onlineCount = 0;
private static Map<String, WebSocketTest> webSocketMap = new ConcurrentHashMap<>();
private Session session;
private String id;
/**
* 用户第一次建立连接的时候执行的方法
* @param id
* @param session
*/
@OnOpen
public void onOpen(@PathParam("id") String id, Session session){
this.id = id;
this.session = session;
if (!webSocketMap.containsKey(id)) {
//没有建立连接的
webSocketMap.put(id, this);
//注意并发
addOnlineCount();
}
log.info("用户"+id+"连接上webSocket,当前连接人数为"+getOnlineCount());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
if(webSocketMap.containsKey(this.id)){
webSocketMap.remove(this.id);
//从set中删除
subOnlineCount();
}
log.info("用户退出:"+id+",当前在线人数为:" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("用户"+this.id+"发送信息:"+message);
}
/**
* 发生错误的时候调用的方法
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("用户错误:"+this.id+",原因:"+error.getMessage());
error.printStackTrace();
}
/**
* 向执行某个任务的客户端发送消息
*/
public void sendMessage(String message){
this.session.getAsyncRemote().sendText(message);
}
/**
* 向用户id为userId的用户推送消息
* */
public static void sendInfo(String message,String id){
log.info("发送消息到:"+id+",报文:"+message);
if(id != null && webSocketMap.containsKey(id)){
webSocketMap.get(id).sendMessage(message);
}else{
log.error("用户"+id+",不在线!");
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketTest.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketTest.onlineCount--;
}
}
2.4 测试连接
启动服务,根据ip地址和端口建立socket 连接, 点这里在线网站测试
三、总结
其实在一个http服务端上面再部署一下ws 也是没有问题的访问也没有任何问题 他们就是两个不同的协议 一个http协议 一个websocket协议.我们可以在类似于聊天室和浏览器实时获取最新消息的时候用到这个ws协议.无论怎么用都只是一个工具,在这个场景下是否适用罢了。
推荐阅读
-
JAVA WEB快速入门之从编写一个基于SpringBoot+Mybatis快速创建的REST API项目了解SpringBoot、SpringMVC REST API、Mybatis等相关知识
-
JAVA WEB快速入门之环境搭建
-
JAVA WEB快速入门之从编写一个基于SpringMVC框架的网站了解Maven、SpringMVC、SpringJDBC
-
精选开源SpringBoot项目快速入门CRM项目【笔记+源码+文档】
-
没有基础的初学者学java怎样快速入门?超全的学习路线图
-
快速入门介绍Java中强大的String.format()
-
SpringBoot整合Thymeleaf快速入门(附详细教程)
-
springboot快速入门学习之论坛项目01(长期更新)
-
Java快速入门_从这六条技能开始 java多线程数据结构
-
SpringBoot快速入门详解