5

如何在 Java Script 中将大数据发送到 WebSocket?

使用下面的代码,我可以发送 126 个字符的数据,但不能超过这个。(用 C# 编写)

public static void SendData(string text)
    {

        foreach (SocketClient client in ClientList)
        {
            if (client.Client.Connected)
            {
                try
                {

                    NetworkStream l_Stream = client.Client.GetStream();

                    List<byte> lb = new List<byte>();
                    lb = new List<byte>();
                    lb.Add(0x81);
                    int size = text.Length;
                    lb.Add((byte)size);
                    lb.AddRange(Encoding.UTF8.GetBytes(text));
                    l_Stream.Write(lb.ToArray(), 0, size + 2);

                }
                catch
                {
                    CloseClient(client);
                }
            }
        }
    }
}

有人可以帮帮我吗?我尝试使用很多东西,但没有一个对我有用。

我正在使用 Chrome 25。

4

4 回答 4

25

这是根据 RFC 6455 的 websocket 框架的外观:

  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 ...                |
 +---------------------------------------------------------------+

您正在字节 1 中设置 websocket 帧的有效负载长度(第二个字节 - 第一个字节是字节 0)。一个字节只能有 256 个状态。但是字节 1 的第一位用于屏蔽标志。所以你只能表示从 0 到 127 的值。

当有效载荷长度大于 125 时,您必须将字节 1 设置为 126,并将长度放入字节 2 和 3(“扩展有效载荷长度”)。当您的有效负载甚至超过 65535 字节时,您必须将字节 1 设置为 127 并将有效负载长度放入字节 2-9(“扩展有效负载长度”和“扩展有效负载长度”)。当您的有效负载长度甚至大于 64 位(16 艾字节,或大约 1600 万太字节)时,那么……您应该发送一堆装满硬盘的卡车。

更多细节可以在官方 Websocket RFC中找到。

于 2013-01-02T08:49:45.413 回答
0

您可以向 WebSocket 发送任意大小的数据,但大数据会被分割。

检查这个:https ://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-17#section-5和 5.4

pastebin.com/TxGZaHTY

http://buildnewgames.com/websockets/

了解更多信息。

于 2012-12-31T18:03:16.417 回答
0

引用自此博客。在 WebSocket 服务器中发送和接收的单个有效负载大小可能存在限制。例如,在 tomcat 中,默认为 8192 字节, org.apache.tomcat.websocket.textBufferSizetomcat 的 doc中签出。

因此,请确保您的 WebSocket 服务器中是否有任何有效负载大小限制,如果是,则将其作为部分有效负载接收。

于 2019-04-09T11:29:08.583 回答
-1
package GoodExample;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import sun.misc.BASE64Encoder;

/**
*
* @author
* Anders, Improved by Christopher Price
 */
public class WebRTCSignal {

public static final int MASK_SIZE = 4;
public static final int SINGLE_FRAME_UNMASKED = 0x81;
private ServerSocket serverSocket;
private Socket socket;

public WebRTCSignal() throws IOException {
serverSocket = new ServerSocket(1337);
connect();
}

private void connect() throws IOException {
System.out.println("Listening");
socket = serverSocket.accept();
System.out.println("Got connection");
if(handshake()) {
    listenerThread();
}
}

private boolean handshake() throws IOException {
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

HashMap<String, String> keys = new HashMap<>();
String str;
//Reading client handshake
while (!(str = in.readLine()).equals("")) {
    String[] s = str.split(": ");
    System.out.println();
    System.out.println(str);
    if (s.length == 2) {
    keys.put(s[0], s[1]);
    }
}
//Do what you want with the keys here, we will just use "Sec-WebSocket-Key"

String hash;
try {
    hash = new BASE64Encoder().encode(MessageDigest.getInstance("SHA-    1").digest((keys.get("Sec-WebSocket-Key") + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").getBytes()));
} catch (NoSuchAlgorithmException ex) {
    ex.printStackTrace();
    return false;
}

//Write handshake response
out.write("HTTP/1.1 101 Switching Protocols\r\n"
    + "Upgrade: websocket\r\n"
    + "Connection: Upgrade\r\n"
    + "Sec-WebSocket-Accept: " + hash + "\r\n"
     + "Origin: http://face2fame.com\r\n"
    + "\r\n");

out.flush();

return true;
}

private byte[] readBytes(int numOfBytes) throws IOException {
byte[] b = new byte[numOfBytes];
socket.getInputStream().read(b);
return b;
}

public void sendMessage(byte[] msg) throws IOException {
System.out.println("Sending to client");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream os = new BufferedOutputStream(socket.getOutputStream());
baos.write(SINGLE_FRAME_UNMASKED);
baos.write(msg.length);
baos.write(msg);
baos.flush();
baos.close();
convertAndPrint(baos.toByteArray());
os.write(baos.toByteArray(), 0, baos.size());
os.flush();
}

public void listenerThread() {
Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
    try {
        while (true) {
        System.out.println("Recieved from client: " + reiceveMessage());
        System.out.println("Enter data to send");
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    }
});
t.start();
}

public String reiceveMessage() throws IOException {
byte[] buf = readBytes(2);
//dont use this byte[] buf2 = readBytes(4);
int extendedsize = 0;
System.out.println("Headers:");
if(!convertAndPrintHeader(buf)){ // This means we detected an extended message
    String CaryOverDetectiona = new String("");
    byte[] bufadder1 = buf.clone();
    byte[] bufadder2 = readBytes(2);
    byte[] array1and2 = new byte[bufadder1.length + bufadder2.length];
    System.arraycopy(bufadder1, 0, array1and2, 0, bufadder1.length);
    System.arraycopy(bufadder2, 0, array1and2, bufadder1.length, bufadder2.length);
    for (byte b : array1and2) {
        CaryOverDetectiona = (String.format("%02X ", b));
        System.out.print(CaryOverDetectiona);

}
    int i = ((array1and2[1] & 0xFF) - 0x80);
    //int c = ((array1and2[2] & 0xFF) - 0x80);
    //System.out.println(c+128);
    int j = ((array1and2[3] & 0xFF) - 0x80)+2;
    //System.out.println("The size of this uber message is" + j);
    extendedsize = i+j;
    System.out.println("Extended Size is" + extendedsize);
    //System.exit(0);

}
//convertAndPrint(buf2);// Check out the byte sizes
int opcode = buf[0] & 0x0F;
if (opcode == 8) {
    //Client want to close connection!
    System.out.println("Client closed!");
    socket.close();
    System.exit(0);
    return null;
} else {
   int payloadSize = getSizeOfPayload(buf[1]);
    if (extendedsize>=126){   
    payloadSize = extendedsize;}
    System.out.println("Payloadsize: " + payloadSize);
    buf = readBytes(MASK_SIZE + payloadSize);
    System.out.println("Payload:");
    convertAndPrint(buf);
    buf = unMask(Arrays.copyOfRange(buf, 0, 4), Arrays.copyOfRange(buf, 4, buf.length));

    String message = new String(buf);

    return message;
}
}

private int getSizeOfPayload(byte b) {
//Must subtract 0x80 from masked frames

int a = b & 0xff;
//System.out.println("PAYLOAD SIZE INT" + a);
return ((b & 0xFF) - 0x80);
}

private byte[] unMask(byte[] mask, byte[] data) {
for (int i = 0; i < data.length; i++) {
    data[i] = (byte) (data[i] ^ mask[i % mask.length]);
}
return data;
}
private boolean convertAndPrintHeader(byte[] bytes) {
   StringBuilder sb = new StringBuilder();
   String CaryOverDetection = new String();
   // We must test byte 2 specifically for this. In the next step we add length bytes perhaps?
   //for(int i = 0; i < bytes.length; i++) {
       //}
    for (byte b : bytes) {
        CaryOverDetection = (String.format("%02X ", b));
        if (CaryOverDetection.contains("FE")){

            return false;
        }
        sb.append(String.format("%02X ", b));
    }
    System.out.println(sb.toString());
    return true;

    }

private void convertAndPrint(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
    sb.append(String.format("%02X ", b));
}
System.out.println(sb.toString());
}

public static void main(String[] args) throws IOException, InterruptedException, NoSuchAlgorithmException {
WebRTCSignal j = new WebRTCSignal();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (true) {
   System.out.println("Write something to the client!");
   j.sendMessage(br.readLine().getBytes());
}
}
}
于 2013-12-16T07:26:25.437 回答