赞
踩
我这里的框架是SpringBoot
首先,我们要有一个前端页面
- <!DOCTYPE html>
- <html xmlns:th="http://www.thymeleaf.org"
- xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
- layout:decorate="layout">
- <head>
- <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js" defer></script>
- <meta charset="UTF-8"/>
- <meta name="viewport"
- content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
- <title>websocket</title>
- </head>
- <body>
- <input type="text" placeholder="请输入您想显示的昵称" name="username" id="username" />
- <button onclick="connection()">链接服务器</button>
- <!--<button onclick="send()">发送数据到服务器</button>-->
- <button onclick="closeSocket()">关闭连接</button>
- <p style="border: 1px solid black;width: 680px;height: 500px" id="talkMsg"></p>
- <input id="message"/><button id="sendBtn" onclick="send()">发送</button>
- </body>
- <script>
- let sock=""
- let username=""
- function connection(){
- username = $("#username").val()
- //ws是WebSocket协议
- sock = new WebSocket('ws://localhost:8080/v1/point/' + username);
-
- //WebSocket事件
- sock.onopen = () => {
- console.log("已经与服务器建立连接.")
- }
- sock.onmessage = (e) => {
- console.log("\n已获取服务器响应的数据.")
- console.log(e)
- document.getElementById("talkMsg").innerHTML = e.data
- }
- sock.onclose = () => {
- console.log("已关闭与服务器的连接.")
- }
- sock.onerror = (e) => {
- console.log("连接发生异常.")
- console.log(e)
- }
- }
-
-
- /**
- * 发送数据到服务端
- */
- function send() {
- // sock.send(JSON.stringify({'message': ' hello world! '}))
- // sock.send(JSON.stringify({'message': document.getElementById("message").value }))
- if(document.getElementById("message").value===""){
- alert("抱歉,消息不能为空^_^")
- }else{
- var message = username + ":" +document.getElementById("message").value
- sock.send(message)
- //发送完信息之后输入框变为空
- document.getElementById("message").value=""
- document.getElementById("talkMsg").innerHTML=""
- }
- }
-
- /**
- * 关闭当前用户与WebSocket的连接
- */
- function closeSocket() {
- //代码只能是 1000,或者[3000, 4999]之间
- let code = 3000;
- let reason = "我想关闭连接!";
- sock.close(code, reason)
- }
- </script>
- </html>

其次,要有相关配置类以及Controller
配置类
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.socket.server.standard.ServerEndpointExporter;
-
- @Configuration //标明该类是配置类
- public class WebSocketConfig {
- /**
- * @Bean 注解会把该方法的返回值当做一个JavaBean,存放在Spring上下文中,以供使用
- * ServerEndpointExporter类的作用是,会扫描所有的服务器端点,
- * 把带有 @ServerEndpoint 注解的所有类都添加进来
- * @return
- */
- @Bean
- public ServerEndpointExporter serverEndpointExporter() {
- return new ServerEndpointExporter();
- }
- }

Controller
- import org.springframework.stereotype.Component;
-
- import javax.websocket.*;
- import javax.websocket.server.PathParam;
- import javax.websocket.server.ServerEndpoint;
- import java.io.IOException;
- import java.util.Map;
- import java.util.Set;
- import java.util.concurrent.ConcurrentHashMap;
-
- /**
- * 该类是用于ws的
- * value:当前 WebSocket 服务的访问(监听)地址
- */
- @Component //生产对象,声明为类
- @ServerEndpoint(value = "/v1/point/{username}") //表明监听地址
- public class EndPointController {
-
- //存储用户,通过一个Map来完成存储
- private static final Map<String,EndPointController> online = new ConcurrentHashMap<>();
-
- //发送数据是通过session对象实现的,那么就要给每个用户一个session对象
- private Session session;
-
- //记录所发出的信息
- private static StringBuffer stringBuffer = new StringBuffer();
- //以下方法都是被触发,而不是访问
- /**
- * 连接建立时被调用。
- */
- @OnOpen
- public void onOpen(@PathParam("username") String username, Session session, EndpointConfig config) throws IOException {
- // System.out.println("连接已经建立.");
- this.session = session; //等号之前的session指的是第24行的,后面的是该方法的
- online.put(username,this);
- //给前端的控制台返回数据
- // session.getBasicRemote().sendText(username+"已加入群聊");
- String message = username + "已加入群聊";
- stringBuffer.append(message + "<br/>");
- // broadcastAllUsers(stringBuffer.toString());
- }
-
- /**
- * 收到消息时被调用。
- * @param message 前端传递过来的消息。
- * @param session
- */
- @OnMessage
- public void onMessage(String message, Session session) throws IOException {
- // System.out.println("收到了消息:" + message);
- //将消息推送到前端
- // session.getBasicRemote().sendText("谢谢,我收到了你的消息:" + message);
-
- stringBuffer.append(message);
- broadcastAllUsers(stringBuffer.toString());
- }
-
- /**
- * 连接关闭时被调用.
- *
- * @param session
- * @param reason 关闭的理由
- */
- @OnClose
- public void onClose(Session session, CloseReason reason) {
- System.out.println("连接已关闭,关闭理由:" + reason);
- }
-
- /**
- * 当连接发生异常时被调用
- *
- * @param session
- * @param e
- */
- @OnError
- public void onError(Session session, Throwable e) {
- System.out.println("连接发生异常:" + e.getMessage());
- e.printStackTrace();
- }
-
- //遍历map将数据发送给每个用户
- private void broadcastAllUsers(String message) throws IOException {
- Set<String> names = online.keySet(); //keySet返回所有key值列表
- for (String name : names) {
- EndPointController endPoint = online.get(name);
- //将数据发送给每一个人
- stringBuffer.setLength(0);
- stringBuffer.append(message+ "<br/>");
- endPoint.session.getBasicRemote().sendText(stringBuffer.toString());
- // System.out.println(stringBuffer.toString());
- }
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。