websocket

HTML5中的WebSocket是个非常不错的技术,通过该技术可以像java中的socket一样可以在浏览器和服务器直接建立socket实现实时双向通讯.

 

目前支持webSocket客户端有Firefox 4Chrome 4Opera 10.70以及Safari 5等,android手机上的webkit等支持html5的都支持,在客户端除了直接使用websocketapi也可以使用jquery.socket.jsatmosphere.js socket.io

 

Java服务器支持webSockettomcat 7.0.27, Netty 3.3.x,Jetty 7.x,GlassFish 3.1.2,比她们更高的版本当然也支持了

 

开始写第一个程序:

首先写一个websockethelloworld,我这里客户端使用websocket原生api,服务器端使用tomcat 7

1.写客户端脚本,在页面中插入以下脚本:

思路:打开一个连接,为连接创建事件监听器(接收服务器的消息),发送消息到到服务器

<scripttype="text/javascript">

   var socket = newWebSocket('ws://127.0.0.1:8080/websocket_test/helloWorld');

  socket.onopen= function(event){

        socket.send('I am the client and I\'m listening!');

        socket.onmessage= function(event){

           alert('来自服务器的消息:'+event.data);

        };

  socket.onclose= function(event){

        //socket关闭

     };

  };

</script>

2.服务器端:接收到消息给客户端回复一个消息

 <servlet>

   <servlet-name>HelloWorldWebSocketServlet</servlet-name>

   <servlet-class>com.auscend.servlet.HelloWorldWebSocketServlet</servlet-class>

 </servlet>

 <servlet-mapping>

   <servlet-name>HelloWorldWebSocketServlet</servlet-name>

   <url-pattern>/helloWorld</url-pattern>

 </servlet-mapping>

 

 

packagecom.auscend.servlet;

importjava.io.IOException;

importjava.nio.ByteBuffer;

importjava.nio.CharBuffer;

importjavax.servlet.http.HttpServletRequest;

importorg.apache.catalina.websocket.MessageInbound;

importorg.apache.catalina.websocket.StreamInbound;

importorg.apache.catalina.websocket.WebSocketServlet;

importorg.apache.catalina.websocket.WsOutbound;

 

publicclassHelloWorldWebSocketServletextendsWebSocketServlet {

  privatestaticfinallongserialVersionUID =1123456L;

  @Override

  protectedStreamInbound createWebSocketInbound(String subProtocol,

         HttpServletRequestrequest) {

     returnnewMessageInbound() {

        @Override

        protectedvoidonTextMessage(CharBuffer charBuffer)throwsIOException {

            System.out.println("收到来自客户端的消息:"+charBuffer);

            WsOutboundout=this.getWsOutbound();

            CharBufferbuffer=CharBuffer.wrap("I'am server,I recevied yourmessage:"+charBuffer);

            out.writeTextMessage(buffer);

            out.flush();

         }

        @Override

        protectedvoidonBinaryMessage(ByteBuffer byteBuffer)throwsIOException {}

      };

   }

}

服务器端支持websocket由于要使用tomcat7中的api,这里要导入catalina.jartomcat-coyote.jar这两个包,不过不要把这个两个包放在WEB-INF下,因为我们不需要把这两个包部署到tomcat中,部署过去会出错(参考http://blog.csdn.net/meiwen1111/article/details/7792923)

 

就上面的代码,简单补充说明:

客户端:

         Websocketapihttp://www.w3.org/TR/websockets/  中文:http://www.w3.org/html/ig/zh/wiki/WebSocket

         Api中描述了WebSocket的接口

[Constructor(DOMString url, optional (DOMString or DOMString[]) protocols)]
/**
new WebSocket(url,protocols)第一个参数是url,第二个参数是一个协议或者协议数组,可以不写,上面的例子中使用ws://127.0.0.1:8080/websocket_test/helloWorld 做为url,其中wshttp一样,表示什么协议。怎么连接和封装数据包。
**/
 
interface WebSocket : EventTarget {
  readonly attribute DOMString url; //当前对象连接的url
 
  // ready state
  const unsigned short CONNECTING = 0;  // 还没建立连接
  const unsigned short OPEN = 1;     // 建立了连接
  const unsigned short CLOSING = 2;  // 正在关闭连接 一般是 close()方法已经被调用 
  const unsigned short CLOSED = 3;  //连接已经关闭
  readonly attribute unsigned short readyState;  //当前对象的状态,上面的四个值
  readonly attribute unsigned long bufferedAmount; //排队等待发送的字节数
 
  // networking
           attribute EventHandler onopen; //连接建立时做什么
           attribute EventHandler onerror; //发生错误时做什么
           attribute EventHandler onclose; //关闭连接做什么
  readonly attribute DOMString extensions; //原来扩展
  readonly attribute DOMString protocol;   //协议
  void close([Clamp] optional unsigned short code, optional DOMString reason); 
/**
调用close方法时,可以不写参数。如果提供第一个参数,第一个参数不应该是1000,而应该是3000  4999的数字,这样会抛InvalidAccessError 异常。如果提供第二个参数,第二个参数应该表示出异常的原因,也就是对第一个参数的补充。
**/
 
  // messaging
           attribute EventHandler onmessage; //收到消息做什么
           attribute DOMString binaryType; //设置event.data的类型,你设置成什么websocket就会给你封装成什么类型,常用的几种: arrayBuffer  blob
 
//通过send发送不同类型的数据
  void send(DOMString data);
  void send(Blob data);
  void send(ArrayBuffer data);
  void send(ArrayBufferView data);
 
};

        

这样我们的客户端如何编程就清楚了。

使用tomcat7websocket进行服务器端的编程:文档:http://tomcat.apache.org/tomcat-7.0-doc/api/index.html?org/apache/catalina/websocket/package-summary.html

         WebSocketServlet可以处理客户端websocket的链接,这个类也是HttpServlet的子类,所以他本身就是一个servlet,自己写类继承WebSocketServlet

        如果是处理http请求,那么会调用doGetdoPost也一样,这里对websocket主要是
          protected abstract StreamInbound createWebSocketInbound(String subProtocol,HttpServletRequest request)方法
           用来和客户端建立连接,参数(协议和用来建立连接的请求)基本不使用。这里要返回一个StreamInbound对象用来处理与客户端的连接,相当于javanet包中的Socket对象
          我们在重写这个方法时,要返回一个StreamInbound的对象,自己new一个StreamInbound的子类的对象,我们常用StreamInbound的子类MessageInbound

         MessageInbound请参看api,基于这个类的对象,可以发送数据到客户端,也可以接受客户端的各种类型的数据

        

在网上有关于聊天室的例子,这里说说思路:

         打开网页后,网页中执行脚本和服务器建立websocket连接,服务器就把和客户端对应的StreamInbound对象保存到一个集合中,当客户端有消息发过来时,服务器把这个消息通过StreamInbound的集合发给每个其他客户端,网页中收到消息把消息显示在页面上。和java.net.Socket的编程思路一致,如果添加功能,参照java.net.Socket的编程思路。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值