Java WebSocket-1.基础实现

1. 新建Java Web项目

项目目录

2.添加pom依赖

WebScoket包

<!-- https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api -->
<dependency>
    <groupId>javax.websocket</groupId>
    <artifactId>javax.websocket-api</artifactId>
    <version>1.1</version>
    <scope>provided</scope>
</dependency>

json包

<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20180130</version>
</dependency>

3. 代码

3.1 前端

<!DOCTYPE html>
<html lang="en" style="height:100%">
<head>
    <meta charset="UTF-8">
    <title>基于WebSocket的聊天室</title>
</head>
<body style="height:100%">
    登录名:<input type="text" id="username" placeholder="登录名">
    <input type="button" value="连接" id="login">
    <input type="button" value="断开" id="logout" onclick="closeWebSocket()">
    <div id="message_0">欢迎来到聊天室!</div>
    <div id="messages"></div>
    <div id="inputMessage" style="position:absolute;bottom:0">
        To: <input type="text" id="toUsername" value="All" style="width:5em"/>
        <input type="button" name="sendMessage" id="sendMessage" value="发送" onclick="sendMessage()">
        <br>
        <textarea name="message" id="message" cols="30" rows="10"></textarea>
    </div>
</body>
<script type="text/javascript">
    // websocket对象
    var websocket = null;

    // 消息列表元素
    var messages = document.getElementById("messages");

    // 登陆按钮的事件
    document.getElementById("login").addEventListener("click", function () {
        var username = document.getElementById("username").value;
        if (username == "") {
            return false;
        }
        // 判断浏览器是否支持WebSocket
        if (("WebSocket" in window)) {
            websocket = new WebSocket("ws://" + document.location.host + "/websocket/" + username);

            /*
            * WebSocket连接成功事件
            */
            websocket.onopen = function () {
                setInfoMessage("WebScoket连接成功。");
            }

            /*
            * WebSocket接收到消息
            */
            websocket.onmessage = function (event) {
                var div = document.createElement("div");
                div.innerText = event.data;
                messages.appendChild(div)
            }

            /*
            * WebSocket断开连接事件
            */
            websocket.onclose = function () {
                setInfoMessage("WebScoket连接关闭。");
            }

            /*
            * WebSocket异常事件
            */
            websocket.onerror = function () {
                setInfoMessage("WebSocket连接异常。")
            }

            /*
            * 监听窗口离开事件,关闭websocket连接
            */
            window.onbeforeunload = function () {
                closeWebSocket();
            }
        }
        else {
            setInfoMessage("当前浏览器不支持WebSocket!");
        }
    })

    /*
    * 向服务器发送消息
    */
    function sendMessage() {
        if (websocket) {
            // 获取消息内容
            var messageContent = document.getElementById("message").value;
            // 获取目标用户
            var toUsername = document.getElementById("toUsername").value;
            // 构建json格式的消息对象
            var message = "{"
                + "To:" + toUsername+ ","
                + "Message: " + messageContent
                + "}"
            // 发送消息
            websocket.send(message);
        }
        else {
            setInfoMessage("WebSocket未连接。")
        }
    }

    //关闭连接
    function closeWebSocket() {
        if (websocket) {
            websocket.close();
        }
        else {
            setInfoMessage("WebSocket未连接。")
        }
    }

    function setInfoMessage(message) {
        document.getElementById("message_0").innerText = message;
    }

</script>
</html>

3.2 后台

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * @ServerEndpoint注解是websocket的核心注解 作为类层次的注解,它将目标类定义成一个websocket服务器端
 * 注解的值将被用于监听客户端访问的URL地址,用户可以通过该URL访问websocket服务器端
 * 用户用username标注
 */
@ServerEndpoint("/websocket/{username}")
public class WebSocketTest1 {

    // 用户名
    private String username;

    // 和客户端的连接会话
    private Session session;

    // 用一个线程安全的map记录每个客户对应的WebSocket
    private static Map<String, WebSocketTest1> clients
            = new ConcurrentHashMap<String, WebSocketTest1>();


    /**
     * 连接成功调用的函数
     *
     * @param username 用户名
     * @param session  和客户端的会话
     */
    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) {
        this.username = username;
        this.session = session;

        clients.put(username, this);
        sendMessageAll(username + "已连接!当前在线人数:" + clients.size());
        System.out.println(username + "已连接!");
    }

    /**
     * 连接关闭时执行的函数
     *
     * @throws IOException
     */
    @OnClose
    public void onClose() throws IOException {
        clients.remove(username);
        sendMessageAll(username + "断开连接!当前在线人数:" + clients.size());
    }

    /**
     * 接收到消息时执行的函数
     *
     * @param message 接受的消息内容
     * @throws IOException
     */
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        JSONObject jsonTo = new JSONObject(message);
        if (!jsonTo.get("To").equals("All")) {
            message = this.username + "对你说:" + jsonTo.get("Message");;
            sendMessageTo(message, jsonTo.get("To").toString());
        } else {
            message = this.username + "说:" + jsonTo.get("Message");
            sendMessageAll(message);
        }
    }

    /**
     * 发生错误执行的函数
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    /**
     * 向目标用户发送消息
     *
     * @param message 消息内容
     * @param to      目标用户
     * @throws IOException
     */
    private void sendMessageTo(String message, String to) throws IOException {
        for (WebSocketTest1 item : clients.values()) {
            if (item.username.equals(to)) {
                item.session.getAsyncRemote().sendText(message);
            }
        }
    }

    /**
     * 向所有人发送消息
     *
     * @param message 消息内容
     */
    private void sendMessageAll(String message) {
        for (WebSocketTest1 item : clients.values()) {
            item.session.getAsyncRemote().sendText(message);
        }
    }

}

4. 运行结果

运行结果

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券