大概目录结构

SpringBoot中使用WebSocket Demo-LMLPHP

 

依赖只引入了JSP 和SpringBoot整合WebSocket   Spring Web

SpringBoot中使用WebSocket Demo-LMLPHP

 

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
    <title>SpringBoot+WebSocket+JSP</title>
</head>

<body style="margin: 45px;">
    <h4>在线聊天室</h4>
    <div class="form-group">
        <label for="content"></label>
        <textarea id="content" readonly="readonly" cols="80" rows="15"></textarea>
    </div>
    <div class="form-group" style="margin-top: 8px">
        <textarea id="message" cols="80" rows="5" placeholder="请输入消息"></textarea>
        <div style="margin-top: 10px">
            <button id="toSend" class="btn btn-info">发送</button>
            <button id="user_exit" class="btn btn-danger">离开</button>
            <input id="username" value="${username}" style="display: none">
        </div>
    </div>

    <script type="text/javascript">
        $(function () {
            var ws;
            if ("WebSocket" in window) {
                var baseUrl = 'ws://localhost:8080/websocket/';
                var userName = $('#username').val();
                ws = new WebSocket(baseUrl + userName);

                // 连通之后的回调事件,建立连接
                ws.onopen = function () {
                    console.log("建立 websocket 连接...");
                };

                // 接收后台服务端的消息
                ws.onmessage = function (event) {
                    $('#content').append(event.data + '\n\n');
                    console.log("接收到服务端发送的消息..." + event.data + '\n');
                };

                ws.onerror = function (event) {
                    console.log("websocket发生错误..." + event + '\n');
                }

                // 连接关闭的回调事件
                ws.onclose = function () {
                    $('#content').append('[' + userName + '] 已离开!');
                    console.log("关闭 websocket 连接...");
                };
            } else {
                // 浏览器不支持 WebSocket
                alert("您的浏览器不支持WebSocket!");
            }

            // 客户端发送消息到服务器
            $('#toSend').click(function () {
                sendMsg();
            });

            $(document).keyup(function (event) {
                // 回车键事件
                if (event.keyCode == 13) {
                    sendMsg();
                }
            });

            // 发送消息
            function sendMsg() {
                //websocket发送消息
                ws.send($('#message').val());
                $('#message').val("");
            }

            // 退出
            $('#user_exit').click(function () {
                if (ws) {
                    ws.close();
                }
            });
        });
    </script>
</body>
</html>

控制器

@Controller
public class ChatController {

    private AtomicInteger idProducer = new AtomicInteger();

    @RequestMapping("/")
    public String index(Model model) {
        model.addAttribute("username","user" + idProducer.getAndIncrement());
        return "index";
    }
}

配置类

@EnableWebSocket //启用WebSocket支持
@Configuration //表示配置类
public class WebSocketConfig {

    /**
     * 配置ServerEndpointExporter的bean
     *
     * 该Bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
/**
 * 说明:
 * 1、@ServerEndpoint注解中指定WebSocket协议的地址;
 * 2、@OnOpen、@OnMessage、@OnClose、@OnError注解与WebSocket中监听事件对应
 *
 **/
@Slf4j //lombok jar包,帮我们自动生成一些代码:@Data
@Component
@ServerEndpoint("/websocket/{username}")
public class ChatServerEndpoint {

    /**
     * 连接建立时触发
     */
    @OnOpen
    public void openSession(@PathParam("username") String username, Session session) {
        log.info("用户{}登录", username);
        String message = "用户[" + username + "] 已进入聊天室!";
        // 发送登录消息给其他人
        WebSocketUtils.sendMessageAll(message);

        // 获取当前在线人数,发给自己
        String onlineInfo = WebSocketUtils.getOnlineInfo();

        //发送消息
        WebSocketUtils.sendMessage(session, onlineInfo);

        // 添加自己到map中
        WebSocketUtils.CLIENTS.put(username, session);
    }

    /**
     * 客户端接收服务端数据时触发
     */
    @OnMessage
    public void onMessage(@PathParam("username") String username, String message) {
        log.info("发送消息:{}, {}", username, message);
        //广播,把消息同步给其他客户端
        WebSocketUtils.sendMessageAll("[" + username + "] : " + message);
    }

    /**
     * 连接关闭时触发
     */
    @OnClose
    public void onClose(@PathParam("username") String username, Session session) {
        // 当前的Session移除某个用户
        WebSocketUtils.CLIENTS.remove(username);

        // 离开消息通知所有人
        WebSocketUtils.sendMessageAll("[" + username + "] 已离开!");

        try {
            //关闭WebSocket Session会话
            session.close();
            log.info("{} 已退出, onclose", username);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("onClose error", e);
        }
    }

    /**
     * 通信发生错误时触发
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        try {
            //关闭WebSocket Session会话
            session.close();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("onError Exception", e);
        }
        log.info("Throwable msg " + throwable.getMessage());
    }
}
public final class WebSocketUtils {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketUtils.class);

    /**
     * 存储WebSocket session
     * <p>
     * 用户名为key,WebSocket Session对象为value
     */
    public static final Map<String, Session> CLIENTS = new ConcurrentHashMap<>();

    /**
     * 使用连接发送数据
     *
     * @param session 用户session
     * @param message 发送内容
     */
    public static void sendMessage(Session session, String message) {
        if (session == null) {
            return;
        }
        final RemoteEndpoint.Basic basic = session.getBasicRemote();
        if (basic == null) {
            return;
        }
        try {
            //发送
            basic.sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("sendMessage IOException ", e);
        }
    }

    /**
     * 发送消息给其他所有人
     *
     * @param message
     */
    public static void sendMessageAll(String message) {
        CLIENTS.forEach((sessionId, session) -> sendMessage(session, message));
    }

    /**
     * 获取所有在线用户
     */
    public static String getOnlineInfo() {
        Set<String> userNames = CLIENTS.keySet();
        if (userNames.size() == 0) {
            return "当前无人在线...";
        }
        return CLIENTS.keySet().toString() + "在线";
    }
}

SpringBoot中使用WebSocket Demo-LMLPHP

 

04-09 13:41