微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – 如何使用java服务器将消息发送到特定的websocket连接

我是WebSockets的新手.

我已经在WebSockets中进行了简单的服务器端客户端聊天.

现在我正在尝试使客户端 – 客户端 – 客户端聊天应用程序.

我有一个问题,在java服务器我们如何可以发送一个消息到特定的WebSocket连接.

如果用户A想要向用户B发送消息.

那么如何管理User-B正在使用这个或那个连接或发送一个消息到该特定的连接?

我在谷歌搜索太多,但找不到任何好处.

解决方法

你必须为此设计一个架构.

当客户端建立与服务器的连接(打开WebSocket)时,服务器必须将连接保持在某个位置(无论您使用Java后端识别与您所使用的Java后端的特定连接),数据结构将依赖于你想做什么一个好的标识符就是用户提供的ID(比如连接到同一个服务器的另一个对等体尚未选择的昵称).否则,只需使用套接字对象作为唯一标识符,并且在前端列出其他用户时,将它们与其唯一标识符相关联,以便客户端可以向特定对等体发送消息.

如果客户端要与另一个特定客户端进行聊天,则HashMap将是数据结构的不错选择,因为您可以将客户端的唯一ID映射到套接字,并在散列表中找到O(1)中的条目.

如果要将客户端的消息广播到所有其他客户端,虽然HashMap也可以很好地运行(如HashMap.values()),但您可以使用一个简单的列表,将传入的消息发送到除原始发件人之外的所有连接的客户端.

当然,您也想从数据结构中删除一个客户端,当您丢失与它的连接时,这很容易使用WebSocket(您正在使用的Java框架应该在套接关闭时回拨).

这是一个使用Jetty 9 WebSocket(和JDK 7)的(几乎完整的)示例:

package so.example;
import java.io.IOException;
import java.util.HashMap;

import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;

@WebSocket
public class MyWebSocket {
    private final static HashMap<String,MyWebSocket> sockets = new HashMap<>();
    private Session session;
    private String myUniqueId;

    private String getMyUniqueId() {
        // unique ID from this class' hash code
        return Integer.toHexString(this.hashCode());
    }

    @OnWebSocketConnect
    public void onConnect(Session session) {
        // save session so we can send
        this.session = session;

        // this unique ID
        this.myUniqueId = this.getMyUniqueId();

        // map this unique ID to this connection
        MyWebSocket.sockets.put(this.myUniqueId,this);

        // send its unique ID to the client (JSON)
        this.sendClient(String.format("{\"msg\": \"uniqueId\",\"uniqueId\": \"%s\"}",this.myUniqueId));

        // broadcast this new connection (with its unique ID) to all other connected clients
        for (MyWebSocket dstSocket : MyWebSocket.sockets.values()) {
            if (dstSocket == this) {
                // skip me
                continue;
            }
            dstSocket.sendClient(String.format("{\"msg\": \"newClient\",\"newClientId\": \"%s\"}",this.myUniqueId));
        }
    }

    @OnWebSocketMessage
    public void onMsg(String msg) {
        /*
         * process message here with whatever JSON library or protocol you like
         * to get the destination unique ID from the client and the actual message
         * to be sent (not shown). also,make sure to escape the message string
         * for further JSON inclusion. 
         */
        String destUniqueId = ...;
        String escapedMessage = ...;

        // is the destination client connected?
        if (!MyWebSocket.sockets.containsKey(destUniqueId)) {
            this.sendError(String.format("destination client %s does not exist",destUniqueId));
            return;
        }

        // send message to destination client
        this.sendClient(String.format("{\"msg\": \"message\",\"destId\": \"%s\",\"message\": \"%s\"}",destUniqueId,escapedMessage));
    }

    @OnWebSocketClose
    public void onClose(Session session,int statusCode,String reason) {
        if (MyWebSocket.sockets.containsKey(this.myUniqueId)) {
            // remove connection
            MyWebSocket.sockets.remove(this.myUniqueId);

            // broadcast this lost connection to all other connected clients
            for (MyWebSocket dstSocket : MyWebSocket.sockets.values()) {
                if (dstSocket == this) {
                    // skip me
                    continue;
                }
                dstSocket.sendClient(String.format("{\"msg\": \"lostClient\",\"lostClientId\": \"%s\"}",this.myUniqueId));
            }
        }
    }

    private void sendClient(String str) {
        try {
            this.session.getRemote().sendString(str);
        } catch (IOException e) {
            e.printstacktrace();
        }
    }

    private void sendError(String err) {
        this.sendClient(String.format("{\"msg\": \"error\",\"error\": \"%s\"}",err));
    }
}

代码是自解释的.关于JSON格式化和解析,Jetty在包org.eclipse.jetty.util.ajax中有一些有趣的工具.

还要注意,如果您的WebSocket服务器框架不是线程安全的,则需要同步数据结构,以确保没有数据损坏(这里是MyWebSocket.sockets).

原文地址:https://www.jb51.cc/js/153023.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐