基于mina的websocket初步实现

来源:互联网 发布:js原生input 隐藏光标 编辑:程序博客网 时间:2024/06/07 23:27

  package com.codecronch.util.net.websocket;

  import java.security.MessageDigest;

  import java.util.regex.Matcher;

  import java.util.regex.Pattern;

  import org.apache.mina.core.buffer.IoBuffer;

  import org.apache.mina.core.session.IoSession;

  import org.apache.mina.filter.codec.CumulativeProtocolDecoder;

  import org.apache.mina.filter.codec.ProtocolDecoderOutput;

  import com.codecronch.util.net.http.HttpUtil;

http://yueyang.uz.taobao.com/

http://www.huihui.cn/share/32960004
http://www.huihui.cn/share/32958280
http://www.huihui.cn/share/32957358
http://www.huihui.cn/share/32956760
http://www.huihui.cn/share/32955260
http://www.huihui.cn/share/32954604
http://www.huihui.cn/share/32954146
http://www.huihui.cn/share/32953522
http://www.huihui.cn/share/32952548
http://www.huihui.cn/share/32950878
http://www.huihui.cn/share/32949902
http://www.huihui.cn/share/32949532
http://www.huihui.cn/share/32948930
http://www.huihui.cn/share/32252372
http://www.huihui.cn/share/32251552
http://www.huihui.cn/share/32251048
http://www.huihui.cn/share/32250130
http://www.huihui.cn/share/32249588
http://www.huihui.cn/share/29997150
http://www.huihui.cn/share/29996422
http://www.huihui.cn/share/29995536
http://www.huihui.cn/share/29994856
http://www.huihui.cn/share/29993976

http://www.kingmoke.cn
http://www.lvsenvshen.cn
http://www.shmcauto.com.cn
http://www.tsjqwj.com.cn
http://www.ptsbw.com.cn
http://www.sonqi.net.cn
http://www.tzcxdd.com
http://www.gongneihzp.com
http://www.aivino.com.cn
http://www.xycarpet.cn

http://yueyang.uz.taobao.com/

http://yueyang.uz.taobao.com/



  /**

  *

  * @author lzrzhao

  * 2014-2-10

  */

  public class WebSocketDecoder extends CumulativeProtocolDecoder {

  private static final int SESSION_TAG_SHAKE_HANDS=1;//会话握手标识 用来标识是否握手

  private static final String WEBSOCKET_GUID="258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

  public static final byte FIN = 0x1; // 1000 0000

  public static final byte OPCODE = 0x0F;// 0000 1111

  public static final byte MASK = 0x1;// 1000 0000

  public static final byte PAYLOADLEN = 0x7F;// 0111 1111

  public static final byte HAS_EXTEND_DATA = 126;

  public static final byte HAS_EXTEND_DATA_CONTINUE = 127;

  @Override

  protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {

  Object attribute = session.getAttribute(SESSION_TAG_SHAKE_HANDS);

  if(attribute==null){

  //握手

  byte[] bytes=new byte[in.limit()];

  in.get(bytes);

  String m = new String(bytes);

  //TODO 验证是否握手请求

  String secKey = getSecWebSocketKey(m);

  secKey += WEBSOCKET_GUID;

  MessageDigest md = MessageDigest.getInstance("SHA-1");

  md.update(secKey.getBytes("iso-8859-1"), 0, secKey.length());

  byte[] sha1Hash = md.digest();

  secKey = base64Encode(sha1Hash);

  String rtn = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "+ secKey + "\r\n\r\n";

  byte[] rtnbytes = rtn.getBytes("utf-8");

  IoBuffer resp = IoBuffer.allocate(rtnbytes.length);

  resp.put(rtnbytes);

  resp.flip();

  session.write(resp);

  session.setAttribute(SESSION_TAG_SHAKE_HANDS,true);

  return false;

  }

  //不够一个消息

  if(in.remaining()<2){

  //消息头不完整

  return false;

  }

  in.mark();

  byte head1 = in.get();

  byte head2 = in.get();

  // int isend =head1>>7&FIN;

  int opcode=head1 & OPCODE;

  if(opcode==8){

  session.close(true);

  return false;

  }

  int ismask=head2>>7&MASK;

  int length=0;

  byte datalength= (byte) (head2& PAYLOADLEN);

  if(datalength<has_extend_data){< p="">

  length=datalength;

  }else if (datalength==HAS_EXTEND_DATA){

  if(in.remaining()<2){

  //消息头不完整

  in.reset();

  return false;

  }

  byte[] extended = new byte[2];

  in.get(extended);

  int shift = 0;

  length = 0;

  for (int i = extended.length - 1; i >= 0; i--) {

  length = length + ((extended[i] & 0xFF) << shift);

  shift += 8;

  }

  }else if(datalength==HAS_EXTEND_DATA_CONTINUE){

  if(in.remaining()<2){

  //消息头不完整

  in.reset();

  return false;

  }

  byte[] extended = new byte[2];

  in.get(extended);

  int shift = 0;

  length = 0;

  for (int i = extended.length - 1; i >= 0; i--) {

  length = length + ((extended[i] & 0xFF) << shift);

  shift += 8;

  }

  }

  byte[] date=new byte[length];

  if(ismask==1){

  if(in.remaining()<4+length){

  in.reset();

  return false;

  }

  // 利用掩码对org-data进行异或

  byte[] mask =new byte[4];

  in.get(mask);

  in.get(date);

  for (int i = 0; i < date.length; i++) {

  // 吧数据进行异或运算

  date[i] = (byte) (date[i] ^ mask[i % 4]);

  }

  }else{

  if(in.remaining()<length){< p="">

  in.reset();

  return false;

  }

  in.get(date);

  }

  return true;

  }

0 0
原创粉丝点击