Java WebSocketサーバを作成していて、クライアント(Chrome Version 57.0.2987.133(64ビット))のオープニングハンドシェイクメッセージを受信しました。下に示された。サーバがペイロードを使い果たしたときにwebsocketプロトコルエラーが発生しました
受信:GET/HTTP/1.1
受信:ホスト:localhostを:6789は
受信:接続:プラグマ:キャッシュなし
受信:のCache-Control:キャッシュなし
受信をアップグレードします が受信:アップグレード:WebSocketを
受信:原産地:http://localhost:8080
受信:秒-のWebSocket-バージョン:13
受信:ユーザーエージェント:Mozillaの/ 5.0(Macintosh版、インテルのMac OS X 10_9_5)のAppleWebKit /537.36(ヤモリ様KHTML)クローム/ 57.0.2987.133サファリ/ 537.36
受付:エンコーディングを受け入れ:gzipで、収縮、SDCH、BR
受付:言語を受け入れ:EN-US、ENを、Q = 0.8
受信:Sec-WebSocket-Key:L1IiUSGijbGmTpthWsebOg ==
受信:Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits送信:HTTP/1.1 101切り替えプロトコル
送信:アップグレード:WebSocketを
を送信:接続:
が送信アップグレード:秒-のWebSocket-受け入れ:受け入れエンコード:送信L5HXnDJGDMYbWr5gRcQMOwKNf3Q =
GZIPを、デフレート
送信:Sec-WebSocket-Extensions:permessage-deflate; client_no_context_takeover; server_no_context_takeover今
、クライアントがメッセージを送信することができ、それは問題なくそうと私のサーバーは、ヘッダバイト0x81と(フィンで応答した場合に自分のコードが正常にjava.util.zip.Deflaterのを使用してそれらを解凍して... 、圧縮なし、テキスト)、0x5に「hello」のバイト(例として)を入力すると、Chromeのjavascriptのwebsocketクライアントは完全に幸せですが、レスポンスを圧縮しようとすると、クライアントは常にエラーコード1002 「Websocket protocol error」というテキストが表示されます。
DEFLATE
public void sendMessageDeflated(String rxMessage, OutputStream streamOut) {
System.out.println("Message back to client is: " + rxMessage);
// And then compress the response and send it out.
Deflater compressor = new Deflater(Deflater.DEFLATED);
try {
int headerLength = 2;
byte unzippedMsg[] = rxMessage.getBytes("UTF-8");
compressor.setInput(unzippedMsg);
compressor.finish();
byte zippedMsg[] = new byte[2048]; // Nasty constant but will have to do for now.
int toCompressLength = unzippedMsg.length;
int compLength = compressor.deflate(zippedMsg, headerLength, zippedMsg.length - headerLength);
compressor.end();
zippedMsg[0] = (byte)0xC1; // FIN bit, compression plus opcode for TEXT MESSAGE
zippedMsg[1] = (byte)((byte)0x00 | (byte)compLength); // No mask on return data.
streamOut.write(zippedMsg, 0, compLength + headerLength);
} catch (IOException ioEx) {
// TBD
System.out.println("IOException: " + ioEx.toString());
} catch (Exception ex) {
// TBD
System.out.println("IOException: " + ex.toString());
}
}
GZIP
public void sendMessageGZipped(String rxMessage, OutputStream streamOut) {
// Do something with the message here...
System.out.println("Message back to client is: " + rxMessage);
// And then compress the response and send it out.
try {
int headerLength = 2;
byte unzippedMsg[] = rxMessage.getBytes("UTF-8");
int toCompressLength = unzippedMsg.length;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzipOut = new GZIPOutputStream(baos);
gzipOut.write(unzippedMsg, 0, toCompressLength);
gzipOut.close();
byte[] payload = baos.toByteArray();
byte header[] = new byte[32];
header[0] = (byte)0xC1; // FIN bit plus opcode for TEXT MESSAGE
header[1] = (byte)((byte)0x00 | (byte)payload.length); // No mask on return data.
streamOut.write(header, 0, 2);
streamOut.write(payload);
} catch (IOException ioEx) {
// TBD
System.out.println("IOException: " + ioEx.toString());
} catch (Exception ex) {
// TBD
System.out.println("IOException: " + ex.toString());
}
}
私はおそらく圧縮されたテキスト=バイナリが、それはうまくいきませんでしたバイナリ思考のためのオペコードへの切り替えを試みました。私が間違ってやったことは本当にわかりません。この実装には、メッセージをまたがるスライディング圧縮ウィンドウは含まれません。私は、応答ヘッダーがそれを明確にすると思います。感謝の意を受けて助けてください。