使用WebSocket实现多人实时聊天


一 应用
本应用使用WebSocket实现多人实时聊天
 
二 代码
客户端代码
Js代码   收藏代码
  1.   
  2.   
  3.   
  4.     "author" content="Yeeku.H.Lee(CrazyIt.org)" />  
  5.     "Content-Type" content="text/html; charset=UTF-8" />  
  6.      使用WebSocket通信   
  7.     "text/javascript">  
  8.         // 创建Web Socket对象  
  9.         var webSocket = new WebSocket("ws://127.0.0.1:30000");  
  10.         webSocket.onopen = function()  
  11.         {  
  12.             // 为onmessage事件绑定监听器,接收消息  
  13.             webSocket.onmessage= function(event)  
  14.             {  
  15.                 // 接收、并显示消息  
  16.                 document.getElementById('show').innerHTML   
  17.                     += event.data + "
    "
    ;  
  18.             }  
  19.         };  
  20.         var sendMsg = function(val)  
  21.         {  
  22.             var inputElement = document.getElementById('msg');  
  23.             // 发送消息  
  24.             webSocket.send(inputElement.value);  
  25.             // 清空单行文本框  
  26.             inputElement.value = "";  
  27.         }  
  28.       
  29.   
  30.   
  31.     overflow-y:auto;border:1px solid #333;" id="show">
  
  • "text" size="80" id="msg" name="msg"/>  
  • "button" value="发送" οnclick="sendMsg();"/>  
  •   
  •   
  •  
    服务器代码
    Js代码   收藏代码
    1. import java.io.*;  
    2. import java.net.*;  
    3. import java.nio.charset.Charset;  
    4. import java.security.MessageDigest;  
    5. import java.util.regex.*;  
    6. import java.util.*;  
    7. import sun.misc.BASE64Encoder;  
    8. /** 
    9.  * Description: 
    10.  * 
      网站: 疯狂Java联盟
       
    11.  * 
      Copyright (C), 2001-2012, Yeeku.H.Lee
       
    12.  * 
      This program is protected by copyright laws.
       
    13.  * 
      Program Name:
       
    14.  * 
      Date:
       
    15.  * @author Yeeku.H.Lee [email protected] 
    16.  * @version 1.0 
    17.  */  
    18. public class ChatServer  
    19. {  
    20.     // 记录所有的客户端Soccket  
    21.     public static List clientSockets  
    22.         = new ArrayList();  
    23.     public ChatServer()throws IOException  
    24.     {  
    25.         // 创建ServerSocket,准备接受客户端连接  
    26.         ServerSocket ss = new ServerSocket(30000);  
    27.         while(true)  
    28.         {  
    29.             // 接收到客户端连接  
    30.             Socket socket = ss.accept();  
    31.             // 将客户端Socket添加到clientSockets集合中  
    32.             clientSockets.add(socket);  
    33.             // 启动线程  
    34.             new ServerThread(socket).start();  
    35.         }  
    36.     }  
    37.     public static void main(String[] args)  
    38.         throws Exception  
    39.     {  
    40.         new ChatServer();  
    41.     }  
    42. }  
    43. class ServerThread extends Thread  
    44. {  
    45.     private Socket socket;  
    46.     public ServerThread(Socket socket)  
    47.     {  
    48.         this.socket = socket;  
    49.     }  
    50.     public void run()  
    51.     {  
    52.         try  
    53.         {  
    54.             // 得到Socket对应的输入流  
    55.             InputStream in = socket.getInputStream();  
    56.             // 得到Socket对应的输出流  
    57.             OutputStream out = socket.getOutputStream();  
    58.             byte[] buff = new byte[1024];  
    59.             String req = "";  
    60.             // 读取数据,此时建立与WebSocket的"握手"。  
    61.             int count = in.read(buff);  
    62.             // 如果读取的数据长度大于0  
    63.             if(count > 0)  
    64.             {  
    65.                 // 将读取的数据转化为字符串  
    66.                 req = new String(buff , 0 , count);  
    67.                 System.out.println("握手请求:" + req);  
    68.                 // 获取WebSocket的key  
    69.                 String secKey = getSecWebSocketKey(req);  
    70.                 System.out.println("secKey = " + secKey);  
    71.                 String response = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: "  
    72.                     + "websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "  
    73.                         + getSecWebSocketAccept(secKey) + "\r\n\r\n";  
    74.                 System.out.println("secAccept = " + getSecWebSocketAccept(secKey));  
    75.                 out.write(response.getBytes());  
    76.             }  
    77.             int hasRead = 0;  
    78.             // 不断读取WebSocket发送过来的数据  
    79.             while((hasRead = in.read(buff)) > 0)  
    80.             {  
    81.                 System.out.println("接收的字节数:" + hasRead);  
    82.                 /* 
    83.                     因为WebSocket发送过来的数据遵循了一定的协议格式, 
    84.                     其中第3个~第6个字节是数据掩码。 
    85.                     从第7个字节开始才是真正的有效数据。 
    86.                     因此程序使用第3个~第6个字节对后面的数据进行了处理 
    87.                 */  
    88.                 for (int i = 0 ; i < hasRead - 6 ; i++ )  
    89.                 {  
    90.                     buff[i + 6] = (byte) (buff[i % 4 + 2] ^ buff[i + 6]);  
    91.                 }  
    92.                 // 获得从浏览器发送过来的数据  
    93.                 String pushMsg = new String(buff  
    94.                     , 6 , hasRead - 6 , "UTF-8");  
    95.                 // 遍历Socket集合,依次向每个Socket发送数据  
    96.                 for (Iterator it = ChatServer.clientSockets.iterator()  
    97.                     ; it.hasNext() ;)  
    98.                 {  
    99.                     try  
    100.                     {  
    101.                         Socket s = it.next();  
    102.                         // 发送数据时,第一个字节必须与读到的第一个字节相同  
    103.                         byte[] pushHead = new byte[2];  
    104.                         pushHead[0] = buff[0];  
    105.                         // 发送数据时,第二个字节记录发送数据的长度  
    106.                         pushHead[1] = (byte) pushMsg.getBytes("UTF-8").length;  
    107.                         // 发送前两个字节  
    108.                         s.getOutputStream().write(pushHead);  
    109.                         // 发送有效数据  
    110.                         s.getOutputStream().write(pushMsg.getBytes("UTF-8"));  
    111.                     }  
    112.                     catch (SocketException ex)  
    113.                     {  
    114.                         // 如果捕捉到异常,表明该Socket已经关闭  
    115.                         // 将该Socket从Socket集合中删除  
    116.                         it.remove();  
    117.                     }  
    118.                 }  
    119.             }  
    120.         }  
    121.         catch (Exception e)  
    122.         {  
    123.             e.printStackTrace();  
    124.         }  
    125.         finally  
    126.         {  
    127.             try  
    128.             {  
    129.                 // 关闭Socket  
    130.                 socket.close();  
    131.             }  
    132.             catch (IOException ex)  
    133.             {  
    134.                 ex.printStackTrace();  
    135.             }  
    136.         }  
    137.     }  
    138.     // 获取WebSocket请求的SecKey  
    139.     private String getSecWebSocketKey(String req)  
    140.     {  
    141.         //构建正则表达式,获取Sec-WebSocket-Key: 后面的内容  
    142.         Pattern p = Pattern.compile("^(Sec-WebSocket-Key:).+",  
    143.                 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);  
    144.         Matcher m = p.matcher(req);  
    145.         if (m.find())  
    146.         {  
    147.             // 提取Sec-WebSocket-Key  
    148.             String foundstring = m.group();  
    149.             return foundstring.split(":")[1].trim();  
    150.         }  
    151.         else  
    152.         {  
    153.             return null;  
    154.         }  
    155.     }  
    156.     // 根据WebSocket请求的SecKey计算SecAccept  
    157.     private String getSecWebSocketAccept(String key)  
    158.         throws Exception  
    159.     {  
    160.         String guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";  
    161.         key += guid;  
    162.         MessageDigest md = MessageDigest.getInstance("SHA-1");  
    163.         md.update(key.getBytes("ISO-8859-1") , 0 , key.length());  
    164.         byte[] sha1Hash = md.digest();  
    165.         BASE64Encoder encoder = new BASE64Encoder();  
    166.         return encoder.encode(sha1Hash);  
    167.     }  
    168. }  
     
     
    三 运行结果
    使用WebSocket实现多人实时聊天_第1张图片
     

    你可能感兴趣的:(使用WebSocket实现多人实时聊天)