WebSocket实现简单的聊天室

创建的maven工程,pom中导入下面两个

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-websocket-api</artifactId>
        <version>8.0.24</version>
    </dependency>

核心类,使用注解,提供访问的url,不需要到xml里配置,然后分别实现@OnOpen,@OnMessage,@OnClose, @OnError即可

@ServerEndpoint(value = "/websocket")
public class WebSocket {
public static Map<String, Session> conns = new HashMap<String, Session>();// session的map

    /**
     * 
     * @Title: OnOpen
     * @Desc: 前端打开链接后,将执行此方法
     *
     * @param session
     * @param config
     *            参数
     *
     */
    @OnOpen
    public void OnOpen(Session session, EndpointConfig config) {
        // System.out.println("---------open---------" + session.getId());
        Session s = null;
        for (String conn : conns.keySet()) {// 遍历已有的session(即已有的连接)
            s = conns.get(conn);
            synchronized (s) {
                try {
                    s.getBasicRemote().sendText(session.getId() + "进入了聊天室");// 根据session发送到对应页面
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        conns.put(session.getId(), session);
    }

    /**
     * 
     * @Title: message
     * @Desc: 消息处理,接收前端的send,并将消息返回给各个前端连接的页面
     *
     * @param message
     * @param session
     *            参数
     *
     */
    @OnMessage
    public void message(String message, Session session) {
        // System.out.println("---------message---------" + session.getId());
        Session s = null;
        for (String conn : conns.keySet()) {
            s = conns.get(conn);
            synchronized (s) {
                try {
                    s.getBasicRemote()
                            .sendText((session.getId() == s.getId() ? "我" : session.getId()) + " 说:" + message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 
     * @Title: close
     * @Desc: 关闭连接,前端close方法时调用
     *
     * @param session
     *            参数
     *
     */
    @OnClose
    public void close(Session session) {
        //System.out.println("---------close---------" + session.getId());
        Session s = null;
        for (String conn : conns.keySet()) {
            s = conns.get(conn);
            if (s != session)
                synchronized (s) {
                    try {
                        s.getBasicRemote().sendText(session.getId() + "离开了聊天室");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        }
        conns.remove(session.getId());
    }

    /**
     * 
     * @Title: close
     * @Desc: 系统出错时调用
     *
     * @param session
     *            参数
     *
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("error");
        error.printStackTrace();
    }
}

前端的jsp页面,没什么特别的。。简单弄个
js中的方法与后台的四个注解的方法对应

<%@ page contentType="text/html;charset=UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>聊天室</title>
<script type="text/javascript">
    var ws;
    var wsUri = "ws://localhost:8080/webChat/websocket";
    ws = new WebSocket(wsUri);
    //接收后台getBasicRemote().sendText()的内容
    ws.onmessage = function(message) {
        writeToScreen(message.data);
    };

    //发送按钮监听,点击按钮后,向后台发送信息,由后台OnMessage接收
    function button() {
        message = document.getElementById('in').value;
        ws.send(message);
    }

    //发生错误时
    ws.onerror = function(msg) {
        writeToScreen('<span style="color:red;">系统出错啦</span>' + msg.data);
        ws.close();
    };

    //聊天信息写入窗口中
    function writeToScreen(message) {
        var pre = document.createElement("p");
        pre.style.wordWrap = "break-word";
        pre.innerHTML = message;
        output.appendChild(pre);
    }

    //当关闭页面时执行,调用后台的OnClose方法
    window.onbeforeunload = function() {
        ws.close();
    };
</script>
</head>
<body>
    <h2>聊天室</h2>
    <div
        style="width: 400px; height: 260px; overflow: scroll; border: 1px solid;"
        id="output"></div>
    <br />
    <div style="text-align: left;">
        <form action="">
            <input id="in" name="message" value="" type="text"
                style="width: 400px; height: 60px; border: 1px solid;"> <br />
            <br /> <input onclick="button()" value="发送" type="button" />
        </form>
    </div>
</body>
</html>

效果演示:
分别打开三个窗口,先打开的窗口收到后打开窗口的进入信息
这里写图片描述




窗口2,发送消息,三个窗口同时收到
这里写图片描述



关闭窗口1,窗口2和3,收到1离开的消息
这里写图片描述

一个简单的聊天室就这样实现了,至于样式那些,就懒得弄了。。。
ps:部分老的浏览器并不支持websocket,特别是某i系列

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值