All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.voovan.http.websocket.WebSocketTools Maven / Gradle / Ivy

There is a newer version: 4.3.8
Show newest version
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();
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy