webSocket向指定用户发送消息

  1. 在pom文件中添加依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
  1. java后台
@Component
@ServerEndpoint(value = "/webSocketToUser/{id}", configurator = WebSocketConfig.class)
public class WebSocketToUser {

    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    private static ConcurrentHashMap<String, WebSocketToUser> webSocketSet = new ConcurrentHashMap<>();
    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private static Session session;

    //指定的sid,具有唯一性
    private static String sid = "";


    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(@PathParam("id") String id, Session session, EndpointConfig config) {
        //获取WebsocketConfig.java中配置的“sessionId”信息值
        String httpSessionId = (String) config.getUserProperties().get("sessionId");
        this.session = session;
        this.sid = id;

        webSocketSet.put(sid, this);     //加入set中
        addOnlineCount();           //在线数加1
        System.out.println("用戶" + sid + "加入!当前在线人数为" + getOnlineCount());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.err.println("来自客户端的消息:" + message);
    }

    /**
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }
    
    public boolean sendToUser(String message, String sendUserId) throws IOException {
        if (webSocketSet.get(sendUserId) != null) {
            if (!sid.equals(sendUserId)) {
                return false;
                //webSocketSet.get(sendUserId).sendMessage("用户" + sendUserId + "发来消息:" + message);
            } else {
                webSocketSet.get(sendUserId).sendMessage(message);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return true;
            }
        } else {
            //如果用户不在线则返回不在线信息给自己
            return false;
        }
    }


    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketToUser.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketToUser.onlineCount--;
    }
}
  1. 配置类
@Component
public class WebSocketConfig extends ServerEndpointConfig.Configurator{

    @Override
    /**
     * 修改握手信息
     */
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        StandardSessionFacade ssf = (StandardSessionFacade) request.getHttpSession();
        if (ssf != null) {
            HttpSession httpSession = (HttpSession) request.getHttpSession();
            //关键操作
            sec.getUserProperties().put("sessionId", httpSession.getId());
            //log.info("获取到的SessionID:" + httpSession.getId());
        }
        super.modifyHandshake(sec, request, response);

    }

    @Bean
    public ServerEndpointExporter serverEndpointConfigurator(){
        return new ServerEndpointExporter();
    }
}
  1. 安全框架拦截器放行webScoket
    在这里插入图片描述
  2. 前端部分
mounted () {
   // 初始化
   this.init()
 },
 
init: function () {
      if (typeof (WebSocket) === "undefined") {
        alert("您的浏览器不支持socket")
      } else {
        // 实例化socket
        //userId是你要发送的用户id
        this.socket = new WebSocket("ws://localhost:8080/webSocketToUser/" + userId)
        // 监听socket连接
        this.socket.onopen = this.open
        // 监听socket错误信息
        this.socket.onerror = this.error
        // 监听socket消息
        this.socket.onmessage = this.getMessage
      }
    },
    open: function () {
      console.log("socket连接成功")
    },
    error: function () {
      console.log("连接错误")
    },
    getMessage: function (msg) {
      this.openMsg(msg.data)
    },
    send: function () {
      this.socket.send(params)
    },
    close: function () {
      console.log("socket已经关闭")
    },
    openMsg (msg) {
      let _self = this;
      this.$notify({
        title: '提示',
        message: msg,
        duration: 0,
        type: 'warning',
        onClose: function () {
          }))
        }
      });
    }

6.注入webSocket, 调用方法

@Autowired
private WebSocketToUser webSocketToUser;

webSocketToUser.sendToUser(自定义消息, 发送用户id);
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
要向指定用户发送消息,您可以在服务器端使用 WebSocket 的 `send()` 方法向特定的用户发送消息。以下是一个示例代码: ```javascript // server.js const express = require('express'); const expressWs = require('express-ws'); const app = express(); expressWs(app); const clients = []; app.ws('/chat', (ws, req) => { ws.on('message', (msg) => { const data = JSON.parse(msg); const { clientId, message } = data; // 找到指定的客户端并向其发送消息 const client = clients.find((c) => c.clientId === clientId); if (client) { client.ws.send(message); } }); ws.on('close', () => { // 移除断开连接的客户端 const index = clients.findIndex((c) => c.ws === ws); if (index !== -1) { clients.splice(index, 1); } }); }); app.post('/register', (req, res) => { const clientId = req.body.clientId; const client = { clientId: clientId, ws: req.ws, }; clients.push(client); res.status(200).send('Client registered successfully'); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` 在上面的示例中,我们添加了一个新的路由 `/register`,用于注册客户端。当客户端发送 POST 请求时,我们从请求体中获取 `clientId`,并将其与客户端的 WebSocket 连接一起添加到 `clients` 数组中。 当服务器收到客户端发送消息时,我们解析该消息,并提取出 `clientId` 和 `message`。然后,我们使用 `find()` 方法在 `clients` 数组中查找具有相应 `clientId` 的客户端。如果找到指定的客户端,我们使用其 WebSocket 连接的 `send()` 方法向其发送消息。 请注意,上述代码只是一个示例,您可能需要根据您的实际需求进行相应的修改和适配。还要确保在客户端注册之前不要尝试向其发送消息,以免出现错误。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值