Java-WebSocket 项目的研究(三) WebSocketClient 类 详解

来源:互联网 发布:淘宝运营策划书 编辑:程序博客网 时间:2024/05/29 02:39
通过之前两篇文章

Java-WebSocket 项目的研究(一) Java-WebSocket类图描述


Java-WebSocket 项目的研究(二) 小试身手:客户端连接服务器并发送消息实例

的介绍我们大概了解到了整个项目的类结构,其中有一个重要的类:WebSocketClient,下面就让我们详细了解一下这个类


首先看一下我们之前的类图关于WebSocketClient的描述,可以看出:

1.继承自WebSocketAdapter

2.依赖于类WebSocketImpl(实际上关于WebSocket核心代码都在类WebSocketImpl里)

3.实现了WebSocket接口(实际上通过类WebSocketImpl实现的)


很简单的,从字面意思我们就大概能猜到WebSocketAdapter是适配器类,架起了WebSocketImplWebSocketClient之间的桥梁,WebSocketImpl是web implementation的缩写,意思就是真正实现了websocket里主要的功能。


然后我们看一下WebSocketClient的几个主要方法:

首先是connect方法

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. /** 
  2.      * Initiates the websocket connection. This method does not block. 
  3.      */  
  4.     public void connect() {  
  5.         if( writeThread != null )  
  6.             throw new IllegalStateException( "WebSocketClient objects are not reuseable" );  
  7.         writeThread = new Thread( this );  
  8.         writeThread.start();  
  9.     }  

我们可以发现:

他其实是起了一个线程,由于WebSocketClient类实现了Runnable接口,因此他会自动去调用run方法,然后我们进一步到run方法里去一探究竟

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. public void run() {  
  2.         try {  
  3.             if( socket == null ) {  
  4.                 socket = new Socket( proxy );  
  5.             } else if( socket.isClosed() ) {  
  6.                 throw new IOException();  
  7.             }  
  8.             System.out.println("---->  "+uri.toString()+"   port: "+getPort() );  
  9.             if( !socket.isBound() )  
  10.                 socket.connect( new InetSocketAddress( uri.getHost(), getPort() ), connectTimeout );  
  11.             istream = socket.getInputStream();  
  12.             ostream = socket.getOutputStream();  
  13.   
  14.             sendHandshake();  
  15.         } catch ( /*IOException | SecurityException | UnresolvedAddressException | InvalidHandshakeException | ClosedByInterruptException | SocketTimeoutException */Exception e ) {  
  16.             onWebsocketError( engine, e );  
  17.             engine.closeConnection( CloseFrame.NEVER_CONNECTED, e.getMessage() );  
  18.             return;  
  19.         }  
  20.   
  21.         writeThread = new Thread( new WebsocketWriteThread() );  
  22.         writeThread.start();  
  23.   
  24.         byte[] rawbuffer = new byte[ WebSocketImpl.RCVBUF ];  
  25.         int readBytes;  
  26.   
  27.         try {  
  28.             while ( !isClosed() && ( readBytes = istream.read( rawbuffer ) ) != -1 ) {  
  29.                 engine.decode( ByteBuffer.wrap( rawbuffer, 0, readBytes ) );  
  30.             }  
  31.             engine.eot();  
  32.         } catch ( IOException e ) {  
  33.             engine.eot();  
  34.         } catch ( RuntimeException e ) {  
  35.             // this catch case covers internal errors only and indicates a bug in this websocket implementation  
  36.             onError( e );  
  37.             engine.closeConnection( CloseFrame.ABNORMAL_CLOSE, e.getMessage() );  
  38.         }  
  39.         assert ( socket.isClosed() );  
  40.     }  


下面我们对上面的代码进行详细研究:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. socket = new Socket( proxy );  

这句显而易见,是创建了一个socket套接字。

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. socket.connect( new InetSocketAddress( uri.getHost(), getPort() ), connectTimeout );  

这句的意思是创建连接,参数就是服务器地址,端口号,超时时间。

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. istream = socket.getInputStream();  

是接受服务器端的数据,关于接受的详细过程,我会在后期的博客中阐述,敬请期待。

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. ostream = socket.getOutputStream();  

是发送数据用的。

其他的先不解释,我们继续之前的流程------connect之后就要发送信息,也就是调用send方法,send方法如下:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. /** 
  2.      * Sends <var>text</var> to the connected websocket server. 
  3.      *  
  4.      * @param text 
  5.      *            The string which will be transmitted. 
  6.      */  
  7.     public void send( String text ) throws NotYetConnectedException {  
  8.         engine.send( text );  
  9.     }  

它调用了engine的send方法,那么engine是啥东东呢,在类的声明处有这么一句话:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. private WebSocketImpl engine = null;  

说明了WebSocketImpl类实现了send的操作。


转自:http://blog.csdn.net/zjh171/article/details/24800493

0 0
原创粉丝点击