Websocket实现Java后台主动推送消息到前台

时间:2024-03-08 09:31:35

写在前面

需求: 项目测试, 缺少用户登录失败给admin推送消息, 想到这个方式, 当用户登录失败时, admin用户会在页面看到咣咣乱弹的alert. 

正文

pom.xml

        <!-- webSocket 开始-->
        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- webSocket 结束-->

Websocket.java

package com.jeecg.webSocket;

import net.sf.json.JSONObject;

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/{username}")
public class WebSocket {
    private static int onlineCount = 0;
    private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
    private Session session;
    private String username;

    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) throws IOException {

        this.username = username;
        this.session = session;

        addOnlineCount();
        clients.put(username, this);
        System.out.println("已连接");
    }

    @OnClose
    public void onClose() throws IOException {
        clients.remove(username);
        subOnlineCount();
    }

    @OnMessage
    public void onMessage(String message) throws IOException {

        JSONObject jsonTo = JSONObject.fromObject(message);
        String mes = (String) jsonTo.get("message");

        if (!jsonTo.get("To").equals("All")){
            sendMessageTo(mes, jsonTo.get("To").toString());
        }else{
            sendMessageAll("给所有人");
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    public void sendMessageTo(String message, String To) throws IOException {
        for (WebSocket item : clients.values()) {
            if (item.username.equals(To) )
                item.session.getAsyncRemote().sendText(message);
        }
    }

    public void sendMessageAll(String message) throws IOException {
        for (WebSocket item : clients.values()) {
            item.session.getAsyncRemote().sendText(message);
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocket.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocket.onlineCount--;
    }

    public static synchronized Map<String, WebSocket> getClients() {
        return clients;
    }
}

fineui_home.jsp

<script>
    var websocket = null;
    var host = document.location.host;

    // 获得当前登录人员的userName
    var username = \'${loginUserName}\';

    // 获取项目名
    var webName = \'${webName}\';

    //判断当前浏览器是否支持WebSocket
    if (\'WebSocket\' in window) {
        // 浏览器支持Websocket
        websocket = new WebSocket(\'ws://\' + host + \'/\' + webName + \'/webSocket/\' + username);
    } else {
        // 浏览器 Not support websocket
    }

    //WebSocket连接发生错误的回调方法
    websocket.onerror = function () {
        setMessageInnerHTML("WebSocket连接发生错误");
    };

    //WebSocket连接成功建立的回调方法
    websocket.onopen = function () {
        setMessageInnerHTML("WebSocket连接成功");
    };

    //接收到消息的回调方法
    websocket.onmessage = function (event) {
        alertTip(event.data);
        // websocket.close();
        // alert("webSocket已关闭!")
    };

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function () {
        closeWebSocket();
    };

    //关闭WebSocket连接
    function closeWebSocket() {
        websocket.close();
    }

    //连接关闭的回调方法
    websocket.onclose = function () {
        setMessageInnerHTML("WebSocket连接关闭");
    };

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML) {
        // document.getElementById(\'message\').innerHTML += innerHTML + \'<br/>\';
    }
</script>

业务调用

WebSocket ws = new WebSocket();
JSONObject jo = new JSONObject();
jo.put("message", "这个比密码不对还想登录!");
jo.put("To", "admin");// 给用户名为admin的用户推送
try {
    ws.onMessage(jo.toString());
} catch (IOException e) {
    e.printStackTrace();
}

感谢