线上客户端地址: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



Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐