springboot 整合websocket 站内消息 (支持广播式和只给一人发送)单独信息发送 信息群发 统计连接数

22 篇文章 0 订阅
8 篇文章 0 订阅

线上客户端地址:http://www.niezhiliang.com:8086/index

线上服务端地址:http://www.niezhiliang.com:8086/admin




请移步到另一篇新写的文章

请移步到另一篇新写的文章

请移步到另一篇新写的文章








第一步:

使用org.springframework.web.socket.server.standard.ServerEndpointExporter.ServerEndpointExporter类。在Spring容器中添加一个该类的实例:

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

第二步:

JSR356定义了WebSocket的规范,Tomcat7中实现了该标准。JSR356 的 WebSocket 规范使用 javax.websocket.*的 API,可以将一个普通 Java 对象(POJO)使用 @ServerEndpoint 注释作为 WebSocket 服务器的端点。

package com.suyu.websocket.server;

import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@ServerEndpoint(value = "/socketServer/{userid}")
@Component
public class SocketServer {

   private Session session;
   private static Map<String,Session> sessionPool = new HashMap<String,Session>();
   private static Map<String,String> sessionIds = new HashMap<String,String>();

   /**
    * 用户连接时触发
    * @param session
    * @param userid
    */
   @OnOpen
   public void open(Session session,@PathParam(value="userid")String userid){
      this.session = session;
      sessionPool.put(userid, session);
      sessionIds.put(session.getId(), userid);
   }

   /**
    * 收到信息时触发
    * @param message
    */
   @OnMessage
   public void onMessage(String message){
      System.out.println("当前发送人sessionid为"+session.getId()+"发送内容为"+message);
   }

   /**
    * 连接关闭触发
    */
   @OnClose
   public void onClose(){
      sessionPool.remove(sessionIds.get(session.getId()));
      sessionIds.remove(session.getId());
   }

   /**
    * 发生错误时触发
    * @param session
    * @param error
    */
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

   /**
    *信息发送的方法
    * @param message
    * @param userId
    */
   public static void sendMessage(String message,String userId){
      Session s = sessionPool.get(userId);
      if(s!=null){
         try {
            s.getBasicRemote().sendText(message);
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
   }

   /**
    * 获取当前连接数
    * @return
    */
   public static int getOnlineNum(){
      return sessionPool.size();
   }

   /**
    * 获取在线用户名以逗号隔开
    * @return
    */
   public static String getOnlineUsers(){
      StringBuffer users = new StringBuffer();
       for (String key : sessionIds.keySet()) {
         users.append(sessionIds.get(key)+",");
      }
       return users.toString();
   }

   /**
    * 信息群发
    * @param msg
    */
   public static void sendAll(String msg) {
      for (String key : sessionIds.keySet()) {
         sendMessage(msg, sessionIds.get(key));
       }
   }

   /**
    * 多个人发送给指定的几个用户
    * @param msg
    * @param persons  用户s
    */

   public static void SendMany(String msg,String [] persons) {
      for (String userid : persons) {
         sendMessage(msg, userid);
      }

   }
}

第三步::编辑Controller

package com.suyu.websocket.controller;

import com.suyu.websocket.server.SocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * websocket
 * 消息推送(个人和广播)
 */
@Controller
public class WebSocketController {
    @Autowired
    private SocketServer socketServer;

    @RequestMapping(value = "/index")
    public String idnex() {

        return "index";
    }

    @RequestMapping(value = "/admin")
    public String admin(Model model) {
        int num = socketServer.getOnlineNum();
        String str = socketServer.getOnlineUsers();
        model.addAttribute("num",num);
        model.addAttribute("users",str);
        return "admin";
    }

    /**
     * 个人信息推送
     * @return
     */
    @RequestMapping("sendmsg")
    @ResponseBody
    public String sendmsg(String msg,String username){
        //第一个参数 :msg 发送的信息内容
        //第二个参数为用户长连接传的用户人数
        String [] persons = username.split(",");
        SocketServer.SendMany(msg,persons);
        return "success";
    }

    /**
     * 推送给所有在线用户
     * @return
     */
    @RequestMapping("sendAll")
    @ResponseBody
    public String sendAll(String msg){
        SocketServer.sendAll(msg);
        return "success";
    }

    /**
     * 获取当前在线用户
     * @return
     */
    @RequestMapping("webstatus")
    public String webstatus(){
        //当前用户个数
       int count = SocketServer.getOnlineNum();
       //当年用户的username
       SocketServer.getOnlineUsers();
        return "tongji";
    }
}

第四步:编写客户端页面,由于框架使用的是springboot,所以用了thymeleaf模板

<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>客户端首页</title>
    <script th:src="@{../jquery.min.js}"></script>
</head>
<body>

请输入您的昵称<input type="text" id="username"/>
         <input type="button" value="连接" οnclick="connect()"/>   <br/>
请填写要发送的内容<input type="text" id="writeMsg"/>
         <input type="button" value="发送" οnclick="sendMsg()"/>

<script type="text/javascript">
var ws = null;
var username = $("#username").val()
function connect(){
   if(username!=null){
      if ('WebSocket' in window){
           ws = new WebSocket("ws://localhost:8080/socketServer/"+$("#username").val());    
      }    
       else if ('MozWebSocket' in window){
           ws = new MozWebSocket("ws://localhost:8080/socketServer/"+$("#username").val());    
       }
       else{
           alert("该浏览器不支持websocket");    
       }    
           
           
       ws.onmessage = function(evt) {    
           alert(evt.data);    
       };    
           
       ws.onclose = function(evt) {    
           alert("连接中断");    
       };    
           
       ws.onopen = function(evt) {    
           alert("连接成功");    
       };  
   }else{
      alert("请输入您的昵称");
   }
}    
    
function sendMsg() {    
    ws.send($("#writeMsg").val());    
}    
</script>
</body>
</html>

然后编写服务端发送信息的页面

<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>统计</title>
    <script th:src="@{/jquery.min.js}"></script>
</head>
<body>
            当前在线人数总计<div id="sum" th:text="${num}" ></div> <br/>
           具体人员为:<div id="users" th:text="${users}"></div> <br/>
          发送消息:请输入推送内容<input type="text" id="msg"/>  <br/>
          请输入发送人昵称<input type="text" id="username"/>
            <span>(如果发送多个用户,用户昵称之间用逗号隔开)</span>  <br/>
   <input type="button" value="发送" οnclick="sendMsg()"/>        <br/>
   <input type="button" value="全部发送" οnclick="sendAll()"/>
   <script type="text/javascript">
      function sendMsg(){
         var user = $("#username").val();
         var msg = $("#msg").val();
         if(msg!=null){
            $.ajax({
                    method: 'get',
                    url: '/sendmsg',
                    data:{
                        username: user,
                        msg:msg
                    },
                    success:function(data) {
                        console.log(data);
                    }
                })
         }else{
            alert("请填写要发送的用户昵称或者发送内容");
         }
      }

      function sendAll(){
         var msg = $("#msg").val();
         if(msg!=null){
               $.ajax({
                   method: 'get',
                   url: '/sendAll',
                   data:{
                       msg:msg
                   },
                   success:function(data) {
                       console.log(data);
                   }
               })
         }else{
            alert("请填写要发送的内容");
         }
      }
   </script>
</body>

</html>

效果图







项目源码:https://github.com/niezhiliang/springbootwebsocket



  • 4
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
Spring Boot中使用WebSocket发送信息可以通过以下步骤实现: 1. 添加依赖:在`pom.xml`文件中添加WebSocket相关的依赖,例如: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2. 创建WebSocket配置类:创建一个配置类,用于配置WebSocket相关的Bean和处理器。可以使用`@EnableWebSocket`注解启用WebSocket支持,并实现`WebSocketConfigurer`接口来配置WebSocket的处理器和拦截器。 3. 创建WebSocket处理器:创建一个类,实现`WebSocketHandler`接口,重写相应的方法来处理WebSocket连接、消息发送和接收等操作。 4. 配置WebSocket处理器:在配置类中注册WebSocket处理器,可以使用`registerHandler()`方法将处理器注册到指定的路径上。 5. 创建前端页面:在前端页面中使用JavaScript代码来建立WebSocket连接,并发送和接收消息。 下面是一个简单的示例代码: ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/websocket").setAllowedOrigins("*"); } @Bean public WebSocketHandler myHandler() { return new MyHandler(); } } @Component public class MyHandler implements WebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 连接建立后的处理逻辑 } @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { // 处理接收到的消息 } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { // 处理传输错误 } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { // 连接关闭后的处理逻辑 } @Override public boolean supportsPartialMessages() { return false; } } ``` 在前端页面中,可以使用JavaScript代码来建立WebSocket连接,并发送和接收消息。例如: ```javascript var socket = new WebSocket("ws://localhost:8080/websocket"); socket.onopen = function() { // 连接建立后的处理逻辑 }; socket.onmessage = function(event) { var message = event.data; // 处理接收到的消息 }; socket.onclose = function(event) { // 连接关闭后的处理逻辑 }; function sendMessage() { var message = "Hello, WebSocket!"; socket.send(message); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值