ホームページ >ウェブフロントエンド >htmlチュートリアル >WeChat や QQ などの IM アプリの使用方法 - Websocket_html/css_WEB-ITnose についての話

WeChat や QQ などの IM アプリの使用方法 - Websocket_html/css_WEB-ITnose についての話

WBOY
WBOYオリジナル
2016-06-24 11:18:04869ブラウズ

まえがき

WebSocket との関わりについて: 2 年生のコンピュータネットワークの授業で先生の講義を聞いて初めて WebSocket を使い、卒業後初めて就職しました。私は最近転職して、IM ソーシャル チャット機能を備えたアプリで働いていましたが、今では WebSocket/Socket に関する私の見解の一部を話すことができると思います。 IM チャット アプリを作成したい場合は、WebSocket と Socket の原理を理解する必要があります。

目次

  • 1.WebSocketの使用シナリオ
  • 2.WebSocketの起源
  • 3.WebSocketプロトコルの原理について話す
  • 4.WebSocketとSocketの違いと接続
  • 5.とはiOS プラットフォーム上の WebSocket と Socket について
  • 6. iOS プラットフォームは WebSocket プロトコルをどのように実装しますか
  • 1. WebSocket の使用シナリオ

1. 最も有名なものは WeChat、QQ、およびこのタイプのソーシャルチャットアプリ。このタイプのチャット アプリは、低遅延と高いリアルタイム性が特徴です。インスタント メッセージングは​​、その中で最も要求が厳しいものです。緊急の案件がある場合、ネットワーク環境が良好であれば、このメッセージはクライアントにすぐには送信されず、緊急の案件は終了します。メッセージを受信したばかりの場合は、ソフトウェアに障害が発生しているはずです。 2. 弾幕 そう言えば、誰もがA駅とB駅を思い浮かべたでしょう。確かに、彼らの集中砲火は常に専門分野でした。そしてビデオの場合、おそらく弾幕が本質です。集中砲火の投稿はリアルタイムに表示される必要があり、チャットと同様にリアルタイムである必要があります。 3. マルチプレイヤー ゲーム4. 共同編集 現在、多くのオープンソース プロジェクトは、世界中に散らばる開発者によって共同開発されています。現時点では、Git や SVN などのバージョン管理システムが競合をマージするために使用されています。ただし、複数人によるリアルタイムのオンライン共同編集をサポートするドキュメントがある場合は、この時点で WebSocket が使用され、各編集者が確実に同じドキュメントを編集できるようになります。現時点では、バージョンを使用する必要はありません。 Git や SVN などのコントロールを使用できます。共同編集インターフェイスでは、相手が何を編集したか、誰がどの段落や単語を変更したかをリアルタイムで確認できるためです。 5. 株式ファンドのリアルタイム相場 金融の世界はほぼミリ秒ごとに急速に変化しています。採用されたネットワーク アーキテクチャがリアルタイム要件を満たせない場合、顧客に多大な損失が発生します。ミリ秒以内に株価が急落し始め、数秒後にデータが更新されると、ユーザーはすでに多額の財産を失っている可能性があります。 6. スポーツのライブ最新情報 もちろん、世界中に多くのファンやスポーツ愛好家がいますが、誰もが自分の好きなスポーツ活動を気にするとき、最も気になるのは試合のリアルタイムのステータスです。この種のニュースで最も優れたエクスペリエンスは、Websocket を使用してリアルタイム更新を実現することです。 7. ビデオ会議/チャット ビデオ会議は実際の人々との会議に代わるものではありませんが、世界中の人々がコンピューターの前に集まって会議を行うことができます。全員が集まって会議場のもつれについて話し合う際に、移動に費やす時間を節約できるだけでなく、インターネット接続がある限り、いつでもどこでも会議を開催できます。 8. 位置ベースのアプリケーション モバイル デバイスの GPS 機能を借用して位置ベースのネットワーク アプリケーションを実装する開発者が増えています。ユーザーの位置を追跡すると (たとえば、動きを記録するアプリを実行するなど)、より詳細なデータを収集できます。 9. オンライン教育 オンライン教育も近年急速に発展しています。 Websocket には、会場の制限がなくなり、全国の知識を学びたい学生に合理的にリソースを割り当てることができるため、ビデオ チャット、インスタント チャット、共同作業が可能です。オンラインで他の人と議論します...10. スマート ホーム これも、私が卒業後に入社した素晴らしい IoT スマート ホーム会社です。自宅のスマート デバイスの状態をモバイル アプリ クライアントにリアルタイムに表示する必要があることを考慮すると、Websocket が選択されたことに疑いの余地はありません。 11. まとめ上記で挙げたシナリオに共通するのは、高いリアルタイム性です。 2. WebSocket の起源 1.

初期ポーリングフェーズ

この方法は、クライアントとサーバーは常に接続されており、1 回に 1 回問い合わせるだけです。その間。クライアントは新しいメッセージをポーリングします。このようにして、受信用と送信用の接続が多数存在します。さらに、リクエストが送信されるたびに Http ヘッダーが作成され、大量のトラフィックと CPU 使用率が消費されます。

2.

ロングポーリングフェーズの改良版

ロングポーリングはポーリングの改良版で、クライアントはHTTPをサーバーに送信した後、新しいメッセージがあるかどうかを確認し、新しいメッセージがない場合は待機し続けます。新しいメッセージがある場合は、クライアントに返されます。ネットワーク帯域幅や CPU 使用率などの問題がある程度軽減されます。ただし、この方法にはまだ欠点があります。たとえば、サーバー側のデータが非常に速く更新されると仮定すると、サーバーはクライアントにデータ パケットを送信した後、クライアントから次の Get リクエストを待ってから、データ パケットを送信する必要があります。 2 番目の更新データ パケットをクライアントに送信します。この場合、クライアントがリアルタイム データを表示する最速時間は 2x RTT (ラウンド トリップ タイム) であり、ネットワークが混雑している場合、この時間はユーザーにとって許容できないものになります。株式市場の相場など。さらに、HTTP パケットのヘッダー データの量は多くの場合非常に大きい (通常は 400 バイト以上) のですが、サーバーが実際に必要とするデータは非常に小さい (わずか約 10 バイトの場合もあります) ため、そのようなデータ パケットはよくサーバーで使用されます。定期的な送信は必然的にネットワーク帯域幅を浪費します。

3.WebSocket の誕生

現在緊急に必要とされているのは、クライアントとサーバー間の双方向通信をサポートすることであり、プロトコルのヘッダーは HTTP ヘッダーほど大きくないため、WebSocket が誕生しました。

上の図は Websocket とポーリングの違いです。図から、クライアントがポーリングで多くのリクエストを送信していることがわかりますが、下の図ではアップグレードが 1 つだけあり、非常にシンプルです。効率的。消費量の比較については、下の図をご覧ください

上の図では、まず、ポーリングによって消費されるトラフィックである青いヒストグラムを確認します。 2 番目: ユースケース B: 10,000 クライアントが毎秒ポーリング: ネットワーク スループットは (871 66 Mbps) ユース ケース C: 100,000 クライアントが 1 秒ごとにポーリング: ネットワーク スループットは (871 x 100,000) = 87,100,000 バイト = 696,800,000 ビット/秒2 番目 (665 Mbps) で、Websocket のフレームは 871 バイトではなく 2 バイトのオーバーヘッドです。2 バイトを使用してポーリングの 871 バイトを置き換えるだけです。 ユースケース A: 1,000 クライアントが 1 秒あたり 1 メッセージを受信: ネットワーク スループットは、(2 x 1,000) = 2,000 バイト = 16,000 ビット/秒 (0.015 Mbps)です ユース ケース B: 10,000 クライアントが 1 秒あたり 1 メッセージを受信: ネットワーク スループット(2 x 10,000) = 20,000 バイト = 160,000 ビット/秒 (0.153 Mbps) ユースケース C: 100,000 のクライアントが 1 秒あたり 1 つのメッセージを受信: ネットワーク スループットは (2 x 100,000) = 200,000 バイト = 1,600,000 ビット/秒 (1.526) Mbps) 1 秒あたりのクライアント ポーリング数が同じでも、その数が 10W/秒の高頻度に達すると、ポーリングは 665Mbps を消費しますが、Websocket は 1.526Mbps しか消費せず、ほぼ 435 倍です。 !

3. WebSocket プロトコルの原理について説明します

WebSocket は、ハンドシェイクを実行するために HTTP プロトコルに依存する必要があります。 TCP チャネルであり、HTTP とは関係ありません。

WebSocket のデータ送信はフレーム形式で行われます。たとえば、メッセージはいくつかのフレームに分割され、順番に送信されます。これにはいくつかの利点があります:

1 データのサイズによって引き起こされる不十分な長さフラグを考慮せずに、大きなデータの送信をフラグメントで送信できます。 2 HTTP チャンクと同様に、データの送信中にメッセージを生成できるため、送信効率が向上します。

 0                   1                   2                   3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len |    Extended payload length    | |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           | |N|V|V|V|       |S|             |   (if payload len==126/127)   | | |1|2|3|       |K|             |                               | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + |     Extended payload length continued, if payload len == 127  | + - - - - - - - - - - - - - - - +-------------------------------+ |                               |Masking-key, if MASK set to 1  | +-------------------------------+-------------------------------+ | Masking-key (continued)       |          Payload Data         | +-------------------------------- - - - - - - - - - - - - - - - + :                     Payload Data continued ...                : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |                     Payload Data continued ...                | +---------------------------------------------------------------+
4. WebSocket と Socket の違いと接続

まず第一に、Socket は実際にはプロトコルではありません。これは、OSI モデルのセッション層 (層 5) で動作します。これは、誰もが下位レベルのプロトコル (通常は TCP または UDP) を直接使用できるようにするために存在する抽象化層です。ソケットは TCP/IP プロトコルのカプセル化です。ソケット自体はプロトコルではなく、呼び出しインターフェイス (API) です。

ソケット (一般に「ソケット」とも呼ばれます) は、IP アドレスとポートを記述するために使用され、通信チェーンへのハンドルです。ネットワーク上の 2 つのプログラムは、双方向通信接続を通じてデータを交換します。この双方向リンクの一端は、IP アドレスとポート番号によって一意に決定されます。通常、アプリケーションは「ソケット」を通じてネットワークにリクエストを送信するか、ネットワークリクエストに応答します。

Socket の通信プロセス中、サーバーは接続要求を監視し、クライアントは接続要求を受信し、受信メッセージをクライアントに送信します。確立されています。クライアントとサーバーの両方は、両者間の接続が切断されるまで、相互にメッセージを送信して通信することもできます。

つまり、IM ソーシャル チャット アプリは WebSocket と Socket に基づいて開発できます

5. iOS プラットフォーム上の WebSocket と Socket のオープン ソース フレームワークは何ですか?

Socket オープン ソース フレームワークには、CocoaAsyncSocketWebSocket オープン ソース フレームワークが含まれます: facebook/SocketRocket、 tidwall/SwiftWebSocket

6. iOS プラットフォームに WebSocket プロトコルを実装する方法

Talk は安いです。コードを見せてください — Linus Torvalds

我们今天来看看facebook/SocketRocket的实现方法首先这是SRWebSocket定义的一些成员变量

@property (nonatomic, weak) id <SRWebSocketDelegate> delegate;/** A dispatch queue for scheduling the delegate calls. The queue doesn't need be a serial queue. If `nil` and `delegateOperationQueue` is `nil`, the socket uses main queue for performing all delegate method calls. */@property (nonatomic, strong) dispatch_queue_t delegateDispatchQueue;/** An operation queue for scheduling the delegate calls. If `nil` and `delegateOperationQueue` is `nil`, the socket uses main queue for performing all delegate method calls. */@property (nonatomic, strong) NSOperationQueue *delegateOperationQueue;@property (nonatomic, readonly) SRReadyState readyState;@property (nonatomic, readonly, retain) NSURL *url;@property (nonatomic, readonly) CFHTTPMessageRef receivedHTTPHeaders;// Optional array of cookies (NSHTTPCookie objects) to apply to the connections@property (nonatomic, copy) NSArray<NSHTTPCookie *> *requestCookies;// This returns the negotiated protocol.// It will be nil until after the handshake completes.@property (nonatomic, readonly, copy) NSString *protocol;

下面这些是SRWebSocket的一些方法

// Protocols should be an array of strings that turn into Sec-WebSocket-Protocol.- (instancetype)initWithURLRequest:(NSURLRequest *)request;- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols;- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates;// Some helper constructors.- (instancetype)initWithURL:(NSURL *)url;- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray<NSString *> *)protocols;- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray<NSString *> *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates;// By default, it will schedule itself on +[NSRunLoop SR_networkRunLoop] using defaultModes.- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;- (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;// SRWebSockets are intended for one-time-use only.  Open should be called once and only once.- (void)open;- (void)close;- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason;///--------------------------------------#pragma mark Send///--------------------------------------//下面是4个发送的方法/** Send a UTF-8 string or binary data to the server. @param message UTF-8 String or Data to send. @deprecated Please use `sendString:` or `sendData` instead. */- (void)send:(id)message __attribute__((deprecated("Please use `sendString:` or `sendData` instead.")));- (void)sendString:(NSString *)string;- (void)sendData:(NSData *)data;- (void)sendPing:(NSData *)data;@end

对应5种状态的代理方法

///--------------------------------------#pragma mark - SRWebSocketDelegate///--------------------------------------@protocol SRWebSocketDelegate <NSObject>- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;@optional- (void)webSocketDidOpen:(SRWebSocket *)webSocket;- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload;// Return YES to convert messages sent as Text to an NSString. Return NO to skip NSData -> NSString conversion for Text messages. Defaults to YES.- (BOOL)webSocketShouldConvertTextFrameToString:(SRWebSocket *)webSocket;@end

didReceiveMessage方法是必须实现的,用来接收消息的。下面4个did方法分别对应着Open,Fail,Close,ReceivePong不同状态的代理方法

方法就上面这些了,我们实际来看看代码怎么写

先是初始化Websocket连接,注意此处ws://或者wss://连接有且最多只能有一个,这个是Websocket协议规定的

    self.ws = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@://%@:%zd/ws", serverProto, serverIP, serverPort]]]];    self.ws.delegate = delegate;    [self.ws open];

发送消息

    [self.ws send:message];

接收消息以及其他3个代理方法

//这个就是接受消息的代理方法了,这里接受服务器返回的数据,方法里面就应该写处理数据,存储数据的方法了。- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message{    NSDictionary *data = [NetworkUtils decodeData:message];    if (!data)        return;}//这里是Websocket刚刚Open之后的代理方法。就想微信刚刚连接中,会显示连接中,当连接上了,就不显示连接中了,取消显示连接的方法就应该写在这里面- (void)webSocketDidOpen:(SRWebSocket *)webSocket{    // Open = silent ping    [self.ws receivedPing];}//这是关闭Websocket的代理方法- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean{    [self failedConnection:NSLS(Disconnected)];}//这里是连接Websocket失败的方法,这里面一般都会写重连的方法- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error{    [self failedConnection:NSLS(Disconnected)];}

最后

以上就是我想分享的一些关于Websocket的心得,文中如果有错误的地方,欢迎大家指点!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。