当前位置:   article > 正文

使用websocket-多人实时通讯_websocket 单服务端向多个客户端通信同时通信

websocket 单服务端向多个客户端通信同时通信

HTML 

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>使用websocket-多人实时通讯</title>
  8. </head>
  9. <body>
  10. <div style="width: 600px;height: 240px;overflow-y: auto;border: 1px solid #ddd;" id="show"></div>
  11. <input type="text" size="80" id="msg" name="msg" />
  12. <input type="button" value="发送" onclick="sendMsg()">
  13. <script>
  14. //创建websocket对象
  15. var websocket = new WebSocket('ws://IP:3000');
  16. //当WebSocket 建立网络连接时触发该函数
  17. websocket.onopen = function() {
  18. //为onmessage事件绑定监听器,接收消息
  19. websocket.onmessage = function(event) {
  20. //接收并显示消息
  21. document.getElementById('show').innerHTML += event.data + "<br/>";
  22. }
  23. }
  24. var sendMsg = function() {
  25. var inputEle = document.getElementById('msg');
  26. //发送消息
  27. websocket.send(inputEle.value);
  28. //清空单行文本框
  29. inputEle.value = '';
  30. }
  31. //为onmessage事件绑定监听器,接收消息
  32. websocket.onmessage = function(event) {
  33. //接收消息
  34. alert('收到的消息是:' + event.data);
  35. }
  36. </script>
  37. </body>
  38. </html>

Java

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

使用方式1

Tomcat启动

1. 把项目部署到webapp目录

2. 打开D:\ITData\tomcat\tomcat-8.0\bin -> startup.bat

3. 访问http://localhost:8080/webapp下的项目/...html

使用方式2:使用vscode-ip访问可以实现同区域网段聊天

参考:

websocket实现聊天室

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/898636
推荐阅读
相关标签