Spring Boot統合WebSocket長接続の実際の応用について詳しく説明します。


前言:
一、WebSocketの初めはロバを産み出します。
公式の定義:WebSocketは単一のTCP接続上で全二重通信を行うプロトコルである。WebSocketは、クライアントとサーバとの間のデータ交換をより簡単にし、サービス端末がクライアントにデータを積極的に転送することを可能にする。WebSocket APIでは、ブラウザとサーバは握手を一度だけ完了する必要があり、両者の間で直接に持続的な接続を作成し、双方向のデータ伝送を行うことができる。本当の双方向平等対話であり、サーバープッシュ技術の一つです。
あまりにも公式なので、やはりブロガーが通訳してくれます。WebSocket技術はサービスとclientを一度接続するだけで、サーバーとクライアントの間で頻繁に要求と通信ができます。簡単に乱暴な通訳を加えるとあります。ハハ!)
WebSocket経典の使用シーン:ウェブサイトオンラインチャットシステム、弾幕システム…
臣附议:webSocketの技术は下に兼ね备えることができなくて、低いバージョンのIEに対応しないで、そのためブラウザーのバージョンに依存して、これもまさにwebSocketの非常に著しい欠陥です。
二、WebSocketの出現は一体私達のために何の実際問題を解決しましたか?
伝統的なb/sアーキテクチャでは、サーバがclientにリアルタイムメッセージを送る機能を実現するために、市場上でよく使われる解決策は大きく3つに分類される:
タイムポーリング
クライアントは一定の時間間隔でサービス側に要求を出します。
ロングポーリング
サーバがクライアントにすぐに返信できるデータがないと、空の結果はすぐに返されません。
技術を流用する
クライアントが隠しているウィンドウは、サービス端末に長いポーリングを要求します。
ロングポーリングの仕組み:

これらのプログラムを総合すると、現在私たちが使っているいわゆるリアルタイム技術は本物のリアルタイム技術ではなく、Ajax方式でリアルタイムの効果をシミュレートするだけで、タイミングポーリングはリアルタイムでサービス端末情報のアプリケーションを取得する必要があります。clientはずっとこのように循環しています。serverはずっと新しいニュースがないなら、clientの多くの要求は無効な要求に属しています。多くの無意味なネットワーク転送をもたらします。だから、これは非常に非効率なリアルタイムプログラムです。ロングポーリングはサーバに対する圧力が非常に大きく、サービス先のデータ変更が非常に頻繁であれば、タイミングポーリングと同じです。だから、伝統http要請の実際的な問題を解決するために、WebSocket技術が生まれました。以下のブロガーは、伝統的なHTTPとWebSocketの違いを皆様に生き生きと理解させます。

三、ブロガーがWebSocketを使うシーン
ブロガーは、会社で第三者の映像収集システムを呼び出し、映像の状態が非同期で業務システムに戻るため、業務システムが第三者のフィードバックを受けた場合、フロントユーザーの体験に対して無感知であるため、フロントはページを更新しなければならない。この時はセルフサービスから、clientにリアルタイムで映像収集状態の通知を送るのが一番いいです。前述のような一般的な解決策では、ポーリングのような比較的lowの実現は、ブロガーが技術オタクとして、技術選択としては間違いないです。ハハ…
四、多くないbb、コードを付けます。
本プロジェクトはSprigBoot環境開発に基づいています。
1、websocket座標を導入する

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、Web SocketUtilツール類をカプセル化し、sessionへのリンク、切断接続、プッシュメッセージの簡単な制御を提供する。

 public class WebsocketUtil {
  /**
   *        Session
   */
  private static final Map<String, Session> ONLINE_SESSION = new ConcurrentHashMap<> ();

  /**
   *   session
   * @param userId
   * @param session
   */
  public static void addSession(String userId, Session session){
    //           session  。         ,      。
    ONLINE_SESSION.putIfAbsent ( userId, session );
  }

  /**
   *   session
   * @param userId
   */
  public static void removeSession(String userId){
    ONLINE_SESSION.remove ( userId );
  }

  /**
   *          
   * @param session
   * @param message
   */
  public static void sendMessage(Session session, String message){
    if(session == null){
      return;
    }

    //   
    RemoteEndpoint.Async async = session.getAsyncRemote ();
    async.sendText ( message );
  }

  /**
   *           
   * @param message
   */
  public static void sendMessageForAll(String message) {
    //jdk8    
    ONLINE_SESSION.forEach((sessionId, session) -> sendMessage(session, message));
  }
}
3、WebSocketController
以上のように、簡単なsession管理とメッセージ管理が作成されました。次に、注釈方式を用いて、Spring Bootのwebsocketパッケージで提供する方法を利用して、OOpen、OClose、OnMessageの3つの方法を実現し、OnErr方法を実現して、異常に対処します。コードセグメントは以下の通りです

/**
 * websocket     
 */
@Component
@ServerEndpoint ( value = "/chat/{userid}" )
public class WebsocketController {

  /**
   *     ,    
   * @param userId
   * @param session
   */
  @OnOpen
  public void onOpen( @PathParam ( value = "userid" ) String userId, Session session ) {
    String message ="[" + userId + "]     !!";

    //    session      
    WebsocketUtil.addSession ( userId, session );
    //     ,      
    WebsocketUtil.sendMessageForAll ( message );
  }

  /**
   *     ,    
   *       
   * @param userId
   * @param session
   */
  @OnClose
  public void onClose(@PathParam ( value = "userId" ) String userId, Session session ) {
    String message ="[" + userId + "]      ...";

    //       
    WebsocketUtil.removeSession ( userId );
    //     ,     
    WebsocketUtil.sendMessageForAll ( message );
  }

  /**
   *            
   * @param userId
   * @param session
   */
  @OnMessage
  public void onMessage(@PathParam ( value = "userId" ) String userId, Session session ,String message) {
    String msg ="[" + userId + "]:"+message;

    //     
    WebsocketUtil.sendMessageForAll ( msg );
  }

  /**
   *          
   * @param session
   * @param throwable
   */
  @OnError
  public void onError(Session session, Throwable throwable) {
    try {
      session.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    throwable.printStackTrace();
  }
}
4、ServerEndpointExportを追加してBeanを起動します。

public class DemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

  /**
   *         @ServerEndpoint     Websocket endpoint
   *    ,       servlet  ,
   *        springboot     ,
   *      ServerEndpointExporter,              。
   */
  @Bean
  public ServerEndpointExporter serverEndpointExporter() {
    return new ServerEndpointExporter();
  }
}
その年に踏んだ穴:
注意:websocketEndpointでは、@Autowiredのいくつかの列の注釈を使ってBeanに注入する時、ずっと注入できなくて、空の指針を報告します。springが管理しているのは全部単例で、websocketと衝突しているからです。
解決策:コンテキストを通じてbeanのインスタンスを取得する:Springコンテキストからbeanインスタンスを取得する方法
ここで、Spring Boot統合Websocket長の実際の応用に関する詳細な文章を紹介します。Spring Boot Websocket長の接続内容は以前の文章を検索したり、以下の関連記事を見たりしてください。これからもよろしくお願いします。