com.neovisionaries.ws.client.WebSocketOutputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nv-websocket-client Show documentation
Show all versions of nv-websocket-client Show documentation
WebSocket client implementation in Java.
/*
* Copyright (C) 2015 Neo Visionaries Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.neovisionaries.ws.client;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
class WebSocketOutputStream extends FilterOutputStream
{
public WebSocketOutputStream(OutputStream out)
{
super(out);
}
public void write(String string) throws IOException
{
// Convert the string into a byte array.
byte[] bytes = Misc.getBytesUTF8(string);
write(bytes);
}
public void write(WebSocketFrame frame) throws IOException
{
writeFrame0(frame);
writeFrame1(frame);
writeFrameExtendedPayloadLength(frame);
// Generate a random masking key.
byte[] maskingKey = Misc.nextBytes(4);
// Write the masking key.
write(maskingKey);
// Write the payload.
writeFramePayload(frame, maskingKey);
}
private void writeFrame0(WebSocketFrame frame) throws IOException
{
int b = (frame.getFin() ? 0x80 : 0x00)
| (frame.getRsv1() ? 0x40 : 0x00)
| (frame.getRsv2() ? 0x20 : 0x00)
| (frame.getRsv3() ? 0x10 : 0x00)
| (frame.getOpcode() & 0x0F);
write(b);
}
private void writeFrame1(WebSocketFrame frame) throws IOException
{
// Frames sent from a client are always masked.
int b = 0x80;
int len = frame.getPayloadLength();
if (len <= 125)
{
b |= len;
}
else if (len <= 65535)
{
b |= 126;
}
else
{
b |= 127;
}
write(b);
}
private void writeFrameExtendedPayloadLength(WebSocketFrame frame) throws IOException
{
int len = frame.getPayloadLength();
if (len <= 125)
{
return;
}
if (len <= 65535)
{
// 2-byte in network byte order.
write((len >> 8) & 0xFF);
write((len ) & 0xFF);
return;
}
// In this implementation, the maximum payload length is (2^31 - 1).
// So, the first 4 bytes are 0.
write(0);
write(0);
write(0);
write(0);
write((len >> 24) & 0xFF);
write((len >> 16) & 0xFF);
write((len >> 8) & 0xFF);
write((len ) & 0xFF);
}
private void writeFramePayload(WebSocketFrame frame, byte[] maskingKey) throws IOException
{
byte[] payload = frame.getPayload();
if (payload == null)
{
return;
}
for (int i = 0; i < payload.length; ++i)
{
// Mask
int b = (payload[i] ^ maskingKey[i % 4]) & 0xFF;
// Write
write(b);
}
}
}