软件编程
位置:首页>> 软件编程>> java编程>> Springboot+WebSocket实现一对一聊天和公告的示例代码

Springboot+WebSocket实现一对一聊天和公告的示例代码

作者:一个头发茂密的程序员  发布时间:2022-06-16 11:32:33 

标签:Springboot,WebSocket,聊天

1.POM文件导入Springboot整合websocket的依赖


       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-websocket</artifactId>
           <version>2.1.6.RELEASE</version>
       </dependency>

2.注册WebSocket的Bean交给Spring容器管理


@Configuration
public class WebSocketServiceConfig {
   @Bean
   public ServerEndpointExporter serverEndpointExporter() {
       return new ServerEndpointExporter();
   }
}

3.WebSocket服务端实现

@ServerEndpoint 注解声明为一个WebSocket服务,访问地址为/chat/{username},@Component将其注册为Spring的一个组件,交给Spring进行管理


@ServerEndpoint("/chat/{username}")
@Component
@Slf4j
public class WebSocket {
   //注入dao或者service,注意:因为dao层接口和service层都是单例的Bean
   //webSocket 不是单例的,所以在注入dao或者service时,需要用set方法对其进行注入,保证每一个都是独立的
    private static ChatMapper chatMapper;
     //参数中的ChatMapper  是 单例池中的ChatMapper
   @Autowired
   public void setChatMapper(ChatMapper chatMapperBean){
       WebSocket.chatMapper = chatMapperBean;
   }

//当前连接数
   private static int onLinePersonNum;
   //定义为Map结构,key值代表用户名称或其他唯一标识,Value代表对应的WebSocket连接。
   //ConcurrentHashMap 保证线程安全,用来存放每个客户端对应的WebSocket对象
   private static Map<String,WebSocket> webSocketMap = new ConcurrentHashMap<String, WebSocket>();
  //用户名
   private String username;
   //当前httpSession
   private Session session;

/**
    * 打开链接
    * @param username
    * @param session
    */
   @OnOpen
   public void openConnect(@PathParam("username")String username, Session session){
       this.session = session;
       this.username = username;
       //在线连接数+1
       onlinePerNumAdd();
       //用户名和当前用户WebSocket对象放进Map中
       webSocketMap.put(this.username,this);
       log.info("{}连接服务器成功。。。。",this.username);
   }

/**
    * 关闭连接
    * @param username
    * @param session
    * @PathParam 用来获取路径中的动态参数Key值
    */
   @OnClose
   public void closeConnect(@PathParam("username")String username, Session session){
       webSocketMap.remove(username);
       //在线连接数-1
       onlinePerNumSub();
       log.info("{} 断开连接。。。",username);
   }

/**
    * 错误提示
    */
   @OnError
   public void errorConnect(Session session, Throwable error){
       log.error("websocket连接异常:{}",error.getMessage());
   }

@OnMessage
   public void send(String message, Session session) throws IOException {
       ObjectMapper objectMapper = new ObjectMapper();
       Map map = objectMapper.readValue(message, Map.class);
       sendMessage(map.get("username").toString(),message);
   }

/**
    * 点对点发送
    * @param username
    * @param message
    * @throws IOException
    */
   private void sendMessage(String username,String message) throws IOException {
       WebSocket webSocket = webSocketMap.get(username);
       webSocket.session.getBasicRemote().sendText(message);
   }
    /**
    * 广播类型发送
    * @param message
    * @throws IOException
    */
   private void sendMessage(String message) throws IOException {
       Set<String> keys = webSocketMap.keySet();
       for (String key : keys) {
           WebSocket webSocket = webSocketMap.get(key);
           webSocket.sendMessage(message);
       }
   }

private synchronized static void onlinePerNumAdd(){
       WebSocket.onLinePersonNum ++;
   }
   private synchronized static void onlinePerNumSub(){
       WebSocket.onLinePersonNum --;
   }
   private synchronized static int getOnLinePerNum(){
       return WebSocket.onLinePersonNum;
   }
}

4.webSocket客户端

chat1.html


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <!--    <script src="https://heerey525.github.io/layui-v2.4.3/layui/layui.js"></script>-->
  <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<body>
<!--<button id="user1" onclick="connect()">连接</button>-->
<input id="link" type="text"/>

<input id="sendMsg" type="text"/>
<button onclick="send()">发送</button>

<div id="message">

</div>
</body>

<script type="text/javascript">
  var websocket = null;
  // function connect() {
  //判断当前浏览器是否支持WebSocket  ,主要此处要更换为自己的地址
  if('WebSocket' in window){
      websocket = new WebSocket("ws://localhost:8089/chat/bbb");
  }
  else{
      alert('Not support websocket')
  }
  //连接发生错误的回调方法
  websocket.onerror = function(){
      // setMessageInnerHTML("error");
  };

//连接成功建立的回调方法
  websocket.onopen = function(event){
      console.log("连接成功!!!")
      // setMessageInnerHTML("open");
      $("#link").val("连接成功!!")
  }

//连接关闭的回调方法
  websocket.onclose = function(){
      // setMessageInnerHTML("close");
  }

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
  window.onbeforeunload = function(){
      websocket.close();
  }
  //发送消息
  function send(){
      websocket.send("aaa");
      // onmessage();
  }

//接收到消息的回调方法
  // function onmessage(){
  websocket.onmessage = function(event){
      console.log(event.data)
      // setMessageInnerHTML(event.data);
      $("#message").append("<h1>"+ event.data + "</h1>")
      // }
  }
</script>
</html>

chat2.html


<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
<!--    <script src="https://heerey525.github.io/layui-v2.4.3/layui/layui.js"></script>-->
   <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<body>
<!--<button id="user1" onclick="connect()">连接</button>-->
<input id="link" type="text"/>

<input id="sendMsg" type="text"/>
<button onclick="send()">发送</button>

<div id="message">

</div>
</body>

<script type="text/javascript">
   var websocket = null;
   // function connect() {
       //判断当前浏览器是否支持WebSocket  ,主要此处要更换为自己的地址
       if('WebSocket' in window){
           websocket = new WebSocket("ws://localhost:8089/pushMsg/aaa");
       }
       else{
           alert('Not support websocket')
       }
       //连接发生错误的回调方法
       websocket.onerror = function(){
           // setMessageInnerHTML("error");
       };

//连接成功建立的回调方法
       websocket.onopen = function(event){
           console.log("连接成功!!!")
           // setMessageInnerHTML("open");
           $("#link").val("服务器连接成功!!")
       }

//连接关闭的回调方法
       websocket.onclose = function(){
           // setMessageInnerHTML("close");
       }

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
       window.onbeforeunload = function(){
           websocket.close();
       }
   //发送消息
   function send(){
       websocket.send("bbb");
       // onmessage();
   }

//接收到消息的回调方法
   // function onmessage(){
       websocket.onmessage = function(event){
           console.log(event.data)
           // setMessageInnerHTML(event.data);
           $("#message").append("<h1>"+ event.data + "</h1>")
       // }
   }

</script>
</html>

来源:https://www.jianshu.com/p/980f0100edbc

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com