Websocketはサービス側として情報を送受信するdemo
20248 ワード
Websocketの使用により,前後のデータ間でリアルタイム通信を行うことができる.通常のウェブプログラムは、クライアントによって要求を発行し、サービス側によって要求を受信し、処理を行い、結果をクライアントに返すという流れである.しかし、サービス側のデータの変化頻度が速い場合、クライアントが最新のサービス側のデータをリアルタイムで取得するには、絶えず要求を送信する必要があり、websoceketが握手を行うと、ブラウザとサーバの間にチャネルが確立され、いつでもデータ伝送が可能になります.
Websocketで@Autowired注入bseriesとbeanを使用すると取れない可能性があります.springが管理しているのは単一例(singleton)で、webssocket(マルチオブジェクト)と衝突しているためです.プロジェクトの起動時に初期化すると、websocket(ユーザー接続されていない)が初期化され、springは同時にサービスに注入され、そのオブジェクトのサービスはnullではなく、注入に成功します.ただしspringはデフォルトで管理されているのは単一の例なので、サービスは1回しか注入されません.新しいユーザーがチャットに入ると、システムはまた新しいwebsocketオブジェクトを作成します.spring管理はすべて単一の例であり、2番目のwebsocketオブジェクトにサービスを注入しないため、ユーザー接続で作成したwebsocketオブジェクトであれば、注入できません.
次はwebsocketがサービス側のdemoとして使用されます.
これはwebsocketがサービス側の1つの書き方であり、websocketに接続する際に、ユーザを区別するIDが渡され、ユーザIDがセッションに存在する.ここでのセッションはwebsocket接続を表し、サービス側がフロントエンドにデータを返すときに誰に送信されたかを知ることができる.Websocketの転送情報のデータ型は文字列のみのようで、デフォルトではサイズの制限があります.解決策は後回しにする.
自分でテストするときは、websocketを使ってオンラインテストできます.
受信情報のテストを行います.接続先はws://で始まります.上記のバックエンドコードを例にとると、@Server Endpoint(「/webSocket/{sid}」)注記に必要な接続形式はws://127.0.0.1:8080/webSocket/123です.
接続が成功すれば、メッセージを送受信できます.
Websocketで@Autowired注入bseriesとbeanを使用すると取れない可能性があります.springが管理しているのは単一例(singleton)で、webssocket(マルチオブジェクト)と衝突しているためです.プロジェクトの起動時に初期化すると、websocket(ユーザー接続されていない)が初期化され、springは同時にサービスに注入され、そのオブジェクトのサービスはnullではなく、注入に成功します.ただしspringはデフォルトで管理されているのは単一の例なので、サービスは1回しか注入されません.新しいユーザーがチャットに入ると、システムはまた新しいwebsocketオブジェクトを作成します.spring管理はすべて単一の例であり、2番目のwebsocketオブジェクトにサービスを注入しないため、ユーザー接続で作成したwebsocketオブジェクトであれば、注入できません.
次はwebsocketがサービス側のdemoとして使用されます.
@ServerEndpoint("/webSocket/{sid}")
@Slf4j
@Component
public class WebSocketServer {
/**
* concurrent Set, MyWebSocket 。
*/
private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
/**
* ,
*/
private Session session;
/**
* sid
*/
private String sid="";
// session map
private static Map<String,Object> dataMap = new HashMap<String,Object>();
/**
*
* */
@OnOpen
public void onOpen(Session session,@PathParam("sid") String sid) {
this.session = session;
// session
dataMap.put(sid,session);
// ,
for (WebSocketServer webSocket:webSocketSet) {
if (webSocket.sid.equals(sid)) {
webSocketSet.remove(webSocket);
}
}
webSocketSet.add(this);
this.sid=sid;
log.info(" ");
}
/**
*
*/
@OnClose
public void onClose() {
webSocketSet.remove(this);
log.info(" ");
}
/**
*
* @param message */
@OnMessage
public void onMessage(String message, Session session) {
log.info(" "+sid+" :"+message);
String sid = getSid(session);
if (sid == null) {
return;
}
//
for (WebSocketServer item : webSocketSet) {
try {
item.sendMessage(message,sid);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String getSid(Session session) {
String sid = null;
for (String key:dataMap.keySet()) {
Session cursession = (Session) dataMap.get(key);
if (cursession == session) {
sid = key;
break;
}
}
return sid;
}
@OnError
public void onError(Session session, Throwable error) {
log.error(" ");
error.printStackTrace();
}
/**
*
*/
public void sendMessage(String message, String sid) throws IOException {
Session session = (Session) dataMap.get(sid);
session.getBasicRemote().sendText(message);
}
/**
*
* */
public static void sendInfo(SocketMsg socketMsg, @PathParam("sid") String sid) throws IOException {
String message = JSONObject.toJSONString(socketMsg);
log.info(" "+sid+", :"+message);
for (WebSocketServer item : webSocketSet) {
try {
// sid , null
if(sid==null) {
item.sendMessage(message,sid);
}else if(item.sid.equals(sid)){
item.sendMessage(message,sid);
}
} catch (IOException ignored) { }
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
WebSocketServer that = (WebSocketServer) o;
return Objects.equals(session, that.session) &&
Objects.equals(sid, that.sid);
}
@Override
public int hashCode() {
return Objects.hash(session, sid);
}
}
これはwebsocketがサービス側の1つの書き方であり、websocketに接続する際に、ユーザを区別するIDが渡され、ユーザIDがセッションに存在する.ここでのセッションはwebsocket接続を表し、サービス側がフロントエンドにデータを返すときに誰に送信されたかを知ることができる.Websocketの転送情報のデータ型は文字列のみのようで、デフォルトではサイズの制限があります.解決策は後回しにする.
自分でテストするときは、websocketを使ってオンラインテストできます.
受信情報のテストを行います.接続先はws://で始まります.上記のバックエンドコードを例にとると、@Server Endpoint(「/webSocket/{sid}」)注記に必要な接続形式はws://127.0.0.1:8080/webSocket/123です.
接続が成功すれば、メッセージを送受信できます.