org.voovan.http.websocket.WebSocketTools Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of voovan-framework Show documentation
Show all versions of voovan-framework Show documentation
Voovan is a java framwork and it not depends on any third-party framework.
package org.voovan.http.websocket;
import org.voovan.http.message.Request;
import org.voovan.http.message.packet.Header;
import org.voovan.tools.TBase64;
import org.voovan.tools.log.Logger;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* WebSocket 工具类
*
* @author helyho
*
* Voovan Framework.
* WebSite: https://github.com/helyho/Voovan
* Licence: Apache v2 License
*/
public class WebSocketTools {
private WebSocketTools(){
}
/**
* s是否是 websocket 升级协议
* @param request Http 请求对象
* @return 是否是 Websocket 升级协议
*/
public static boolean isWebSocketUpgrade(Request request) {
Header header = request.header();
return header != null && "websocket".equalsIgnoreCase(header.get("Upgrade"))
&& header.contain("Sec-WebSocket-Key");
}
/**
* 生成协议升级的 KEY
* @param in 协议参数
* @return 协议升级的 KEY
*/
public static String generateSecKey( String in ) {
String seckey = in.trim();
String acc = seckey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
MessageDigest sh1 = null;
try {
sh1 = MessageDigest.getInstance( "SHA" );
return TBase64.encode( sh1.digest(acc.getBytes()) );
} catch ( NoSuchAlgorithmException e ) {
Logger.error("No Such Algorithm.", e);
return null;
}
}
/**
* 将 int 转换成 byte[]
* @param iSource int 值
* @param iArrayLen 数组长度
* @return int 转换后的 byte[]
*/
public static byte[] intToByteArray(int iSource, int iArrayLen) {
byte[] bLocalArr = new byte[iArrayLen];
for (int i = 0; (i < 4) && (i < iArrayLen); i++) {
bLocalArr[i] = (byte) (iSource >> 8 * i & 0xFF);
}
return bLocalArr;
}
/**
* byte 转换成 int
* @param bRefArr byte 数组
* @return int 值
*/
public static int byteToInt(byte[] bRefArr) {
int iOutcome = 0;
byte bLoop;
for (int i = 0; i < bRefArr.length; i++) {
bLoop = bRefArr[i];
iOutcome += (bLoop & 0xFF) << (8 * i);
}
return iOutcome;
}
/**
* 判断缓冲区中的数据是否是一个 WebSocket 帧
* @param buffer 缓冲区对象
* @return WebSocket 帧报文长度,-1不是WebSocket 帧, 大于0 返回的 WebSocket 的长度
*/
public static int isWebSocketFrame(ByteBuffer buffer) {
// 接受数据的大小
int maxpacketsize = buffer.remaining();
// 期望数据包的实际大小
int expectPackagesize = 2;
if (maxpacketsize < expectPackagesize) {
return -1;
}
byte finByte = buffer.get();
boolean fin = finByte >> 8 != 0;
byte rsv = (byte) ((finByte & ~(byte) 128) >> 4);
if (rsv != 0) {
return -1;
}
byte maskByte = buffer.get();
boolean mask = (maskByte & -128) != 0;
int payloadlength = (byte) (maskByte & ~(byte) 128);
int optcode = (byte) (finByte & 15);
if (!fin) {
if (optcode == 9 || optcode == 10 || optcode == 8) {
return -1;
}
}
if (payloadlength >= 0 && payloadlength <= 125) {
} else {
if (optcode == 9 || optcode == 10 || optcode == 8) {
return -1;
}
if (payloadlength == 126) {
expectPackagesize += 2;
byte[] sizebytes = new byte[3];
sizebytes[1] = buffer.get();
sizebytes[2] = buffer.get();
payloadlength = new BigInteger(sizebytes).intValue();
} else {
expectPackagesize += 8;
byte[] bytes = new byte[8];
for (int i = 0; i < 8; i++) {
bytes[i] = buffer.get();
}
long length = new BigInteger(bytes).longValue();
if (length <= Integer.MAX_VALUE) {
payloadlength = (int) length;
}
}
}
expectPackagesize += (mask ? 4 : 0);
expectPackagesize += payloadlength;
// 如果实际接受的数据小于数据包的大小则报错
if (maxpacketsize < expectPackagesize) {
return -1;
} else {
buffer.position(0);
return buffer.remaining();
}
}
}