Websocketはサービス側として情報を送受信するdemo

20248 ワード

Websocketの使用により,前後のデータ間でリアルタイム通信を行うことができる.通常のウェブプログラムは、クライアントによって要求を発行し、サービス側によって要求を受信し、処理を行い、結果をクライアントに返すという流れである.しかし、サービス側のデータの変化頻度が速い場合、クライアントが最新のサービス側のデータをリアルタイムで取得するには、絶えず要求を送信する必要があり、websoceketが握手を行うと、ブラウザとサーバの間にチャネルが確立され、いつでもデータ伝送が可能になります.
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です.
接続が成功すれば、メッセージを送受信できます.