我是新來的WebSockets。如何發送消息到特定的websocket連接使用java服務器
我已經作出的WebSockets一個簡單的服務器 - 客戶端聊天。
,現在我試圖讓客戶端 - 服務器 - 客戶端聊天應用。
我有一個問題,在Java服務器如何才能將消息發送到特定的WebSocket連接。
如果用戶-A想要發送消息給用戶-B。
那我怎麼才能管理該用戶B使用這樣或那樣的連接或將消息發送到特定的連接?
我尋找太多這對谷歌,但找不到什麼好東西。
我是新來的WebSockets。如何發送消息到特定的websocket連接使用java服務器
我已經作出的WebSockets一個簡單的服務器 - 客戶端聊天。
,現在我試圖讓客戶端 - 服務器 - 客戶端聊天應用。
我有一個問題,在Java服務器如何才能將消息發送到特定的WebSocket連接。
如果用戶-A想要發送消息給用戶-B。
那我怎麼才能管理該用戶B使用這樣或那樣的連接或將消息發送到特定的連接?
我尋找太多這對谷歌,但找不到什麼好東西。
你必須爲此設計一個架構。
當客戶端與服務器建立連接(打開WebSocket)時,服務器必須將連接保持在某個位置(無論您如何識別與正在使用的Java後端的特定連接),數據結構這將取決於你想要做什麼。一個好的標識符應該是用戶提供的一個ID(就像一個暱稱,這個暱稱還沒有被另一個連接到同一個服務器的對等端選中)。否則,只需使用套接字對象作爲唯一標識符,並在前端列出其他用戶時,將它們與其唯一標識符相關聯,以便客戶端可以向特定對等方發送消息。
A HashMap
如果客戶端要與另一個特定客戶端聊天,那麼這將是一個很好的選擇,因爲您可以將客戶端的唯一ID映射到套接字並在O(1)中找到條目,在一個哈希表中。
如果要播放從客戶端向所有其他客戶端的消息,雖然HashMap
也工作得很好(有類似HashMap.values()
),你可以使用一個簡單的List
,除了送進來的消息發送給所有連接的客戶端原始發件人。
當然,當你失去與數據結構的連接時,你也希望從數據結構中刪除一個客戶端,這很容易使用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
)。
你可以建議我任何鏈接或網站.....或任何參考代碼...這如何發送潮頭ID的我們怎樣才能把它在地圖???? – manankhh
當然:看到我更新的答案。 – eepp
謝謝你的答案,它真的有用/// .... – manankhh