当前位置:   article > 正文

使用WebSocket实现一个简易的聊天室

使用WebSocket实现一个简易的聊天室

我这里的框架是SpringBoot

首先,我们要有一个前端页面

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org"
  3. xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
  4. layout:decorate="layout">
  5. <head>
  6. <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js" defer></script>
  7. <meta charset="UTF-8"/>
  8. <meta name="viewport"
  9. content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
  10. <title>websocket</title>
  11. </head>
  12. <body>
  13. <input type="text" placeholder="请输入您想显示的昵称" name="username" id="username" />
  14. <button onclick="connection()">链接服务器</button>
  15. <!--<button onclick="send()">发送数据到服务器</button>-->
  16. <button onclick="closeSocket()">关闭连接</button>
  17. <p style="border: 1px solid black;width: 680px;height: 500px" id="talkMsg"></p>
  18. <input id="message"/><button id="sendBtn" onclick="send()">发送</button>
  19. </body>
  20. <script>
  21. let sock=""
  22. let username=""
  23. function connection(){
  24. username = $("#username").val()
  25. //ws是WebSocket协议
  26. sock = new WebSocket('ws://localhost:8080/v1/point/' + username);
  27. //WebSocket事件
  28. sock.onopen = () => {
  29. console.log("已经与服务器建立连接.")
  30. }
  31. sock.onmessage = (e) => {
  32. console.log("\n已获取服务器响应的数据.")
  33. console.log(e)
  34. document.getElementById("talkMsg").innerHTML = e.data
  35. }
  36. sock.onclose = () => {
  37. console.log("已关闭与服务器的连接.")
  38. }
  39. sock.onerror = (e) => {
  40. console.log("连接发生异常.")
  41. console.log(e)
  42. }
  43. }
  44. /**
  45. * 发送数据到服务端
  46. */
  47. function send() {
  48. // sock.send(JSON.stringify({'message': ' hello world! '}))
  49. // sock.send(JSON.stringify({'message': document.getElementById("message").value }))
  50. if(document.getElementById("message").value===""){
  51. alert("抱歉,消息不能为空^_^")
  52. }else{
  53. var message = username + ":" +document.getElementById("message").value
  54. sock.send(message)
  55. //发送完信息之后输入框变为空
  56. document.getElementById("message").value=""
  57. document.getElementById("talkMsg").innerHTML=""
  58. }
  59. }
  60. /**
  61. * 关闭当前用户与WebSocket的连接
  62. */
  63. function closeSocket() {
  64. //代码只能是 1000,或者[3000, 4999]之间
  65. let code = 3000;
  66. let reason = "我想关闭连接!";
  67. sock.close(code, reason)
  68. }
  69. </script>
  70. </html>

其次,要有相关配置类以及Controller

配置类

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.socket.server.standard.ServerEndpointExporter;
  4. @Configuration //标明该类是配置类
  5. public class WebSocketConfig {
  6. /**
  7. * @Bean 注解会把该方法的返回值当做一个JavaBean,存放在Spring上下文中,以供使用
  8. * ServerEndpointExporter类的作用是,会扫描所有的服务器端点,
  9. * 把带有 @ServerEndpoint 注解的所有类都添加进来
  10. * @return
  11. */
  12. @Bean
  13. public ServerEndpointExporter serverEndpointExporter() {
  14. return new ServerEndpointExporter();
  15. }
  16. }

Controller

  1. import org.springframework.stereotype.Component;
  2. import javax.websocket.*;
  3. import javax.websocket.server.PathParam;
  4. import javax.websocket.server.ServerEndpoint;
  5. import java.io.IOException;
  6. import java.util.Map;
  7. import java.util.Set;
  8. import java.util.concurrent.ConcurrentHashMap;
  9. /**
  10. * 该类是用于ws的
  11. * value:当前 WebSocket 服务的访问(监听)地址
  12. */
  13. @Component //生产对象,声明为类
  14. @ServerEndpoint(value = "/v1/point/{username}") //表明监听地址
  15. public class EndPointController {
  16. //存储用户,通过一个Map来完成存储
  17. private static final Map<String,EndPointController> online = new ConcurrentHashMap<>();
  18. //发送数据是通过session对象实现的,那么就要给每个用户一个session对象
  19. private Session session;
  20. //记录所发出的信息
  21. private static StringBuffer stringBuffer = new StringBuffer();
  22. //以下方法都是被触发,而不是访问
  23. /**
  24. * 连接建立时被调用。
  25. */
  26. @OnOpen
  27. public void onOpen(@PathParam("username") String username, Session session, EndpointConfig config) throws IOException {
  28. // System.out.println("连接已经建立.");
  29. this.session = session; //等号之前的session指的是第24行的,后面的是该方法的
  30. online.put(username,this);
  31. //给前端的控制台返回数据
  32. // session.getBasicRemote().sendText(username+"已加入群聊");
  33. String message = username + "已加入群聊";
  34. stringBuffer.append(message + "<br/>");
  35. // broadcastAllUsers(stringBuffer.toString());
  36. }
  37. /**
  38. * 收到消息时被调用。
  39. * @param message 前端传递过来的消息。
  40. * @param session
  41. */
  42. @OnMessage
  43. public void onMessage(String message, Session session) throws IOException {
  44. // System.out.println("收到了消息:" + message);
  45. //将消息推送到前端
  46. // session.getBasicRemote().sendText("谢谢,我收到了你的消息:" + message);
  47. stringBuffer.append(message);
  48. broadcastAllUsers(stringBuffer.toString());
  49. }
  50. /**
  51. * 连接关闭时被调用.
  52. *
  53. * @param session
  54. * @param reason 关闭的理由
  55. */
  56. @OnClose
  57. public void onClose(Session session, CloseReason reason) {
  58. System.out.println("连接已关闭,关闭理由:" + reason);
  59. }
  60. /**
  61. * 当连接发生异常时被调用
  62. *
  63. * @param session
  64. * @param e
  65. */
  66. @OnError
  67. public void onError(Session session, Throwable e) {
  68. System.out.println("连接发生异常:" + e.getMessage());
  69. e.printStackTrace();
  70. }
  71. //遍历map将数据发送给每个用户
  72. private void broadcastAllUsers(String message) throws IOException {
  73. Set<String> names = online.keySet(); //keySet返回所有key值列表
  74. for (String name : names) {
  75. EndPointController endPoint = online.get(name);
  76. //将数据发送给每一个人
  77. stringBuffer.setLength(0);
  78. stringBuffer.append(message+ "<br/>");
  79. endPoint.session.getBasicRemote().sendText(stringBuffer.toString());
  80. // System.out.println(stringBuffer.toString());
  81. }
  82. }
  83. }

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

闽ICP备14008679号