WebSocket 聊天室示例

2018-06-22|来源:

基本思路:
1、用户登录,把用户名存到session中,然后跳转到聊天页面chat.jsp
2、在chat.jsp加载完成后,向WebSocket服务端发起连接请求
3、WebSocket服务端接收到客户端请求后,把session存放在Set集合中,方便以后群聊的时候使用,同时向所有连接的客户端发起欢迎信息
4、实现群聊


用户登录页面,这里简单实现,只要输入一个用户名即可提交

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
<form action="loginServlet" method="post">
    用户名: <input name="username"/><br/>
    <input type="submit"/>
</form>
</body>
</html>


建立一个Servlet接收登录请求,并把该用户保存到Session中,然后跳转到添天页面
package com._656463.demo.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String username = request.getParameter("username");
        HttpSession session = request.getSession();
        session.setAttribute("user", username);
        response.sendRedirect("chat.jsp");
    }
}


web.xml 配置LoginServlet  
<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com._656463.demo.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/loginServlet</url-pattern>
</servlet-mapping>


聊天页面代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title></title>
    <meta name="keywords" content=""/>
    <meta name="description" content=""/>
    <script type="text/javascript">
        var user='${sessionScope.user}';
        var users=[];
        var ws;  // 管理登陆,退出,用户列表的 socket
        var ws2;  // 管理聊天 的 socket
        window.onload= ws_init;
        function  ws_init(){
            var target="ws://192.168.56.101:8080/chat?username="+user;
            if ('WebSocket' in window) {
                ws = new WebSocket(target);
            } else if ('MozWebSocket' in window) {
                ws = new MozWebSocket(target);
            } else {
                alert('WebSocket is not supported by this browser.');
                return;
            }
            ws.onopen=function(){
                showMsg("webSocket通道建立成功!!!");
            };
            ws.onmessage=function(event){
                ;
                console.info(msg);
                if(msg.welcome!=undefined)
                    showMsg(msg.welcome);
                if(msg.usernames!=undefined)
                    showUser(msg.usernames);
                if(msg.from!=undefined){
                    showContent(msg);
                }
            }
        }
        function showMsg(msg){
            var content= document.getElementById("content");
            content.innerHTML+=msg+"<br/>";
        }
        function showUser(users){
            if(users.length==0) return;
            var userList= document.getElementById("userList");
            userList.innerHTML="";
            for(var i=0;i<users.length;i++){
                userList.innerHTML+= users[i]+"<br/>";
            }
        }
        function showContent(msg){
            var content= document.getElementById("content");
            content.innerHTML+=msg.from+"--"+msg.date+"<br/>"+msg.content+"<br/>";
        }
        function ws_send(){
            var msg= document.getElementById("msg");
            var temp="{from:'"+user+"',content:'"+msg.value+"'}";
            ws.send(temp);
            msg.value="";
        }
    </script>
</head>
<body>
<h1>这里是聊天室 , 欢迎 ${sessionScope.user }进入聊天</h1>
<div id="content" style="background-color: aqua; width: 500px; height:400px;float:left;">
   <!-- 这个div显示所有的  聊天信息的内容 -->
</div>
<div id="userList" style="background-color: olive; width: 200px; height:400px;float: left;">
    <!--
        这个div 显示所有的在线用户
        这里要 显示两部分内容 是不是以为这要  两个 webSocket通道才能完成呢??
        一个通道能否完成!!
        回答:  两个webSocket通道 显然更加简单一些啊。。。
     -->
</div>
<div style="margin-top: 10px;  clear: both;">
    <input id="msg"/>
    <button onclick="ws_send();">send</button>
</div>
</body>
</html>


WebSocket实现聊天的服务端程序:
package com._656463.demo.websocket;
import com._656463.demo.vo.Msg;
import com.google.gson.Gson;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
/**
 * 聊天socket
 */
@ServerEndpoint("/chat")
public class ChatSocket {
    private static Set<ChatSocket> ss = new HashSet<ChatSocket>();
    private static List<String> usernames=new ArrayList<String>();
    private Session  session ;
    private String username;
    private Gson gson=new Gson();
    @OnOpen
    public void open(Session session) {
        System.out.println("建立了一个 webSocket通道!!!  sid:" + session.getId());
        String queryString = session.getQueryString();
        this.username = queryString.substring(queryString.indexOf("=") + 1);
        ss.add(this);
        usernames.add(username);
        this.session = session;
        Map<String,Object> welcomeMsg = new HashMap<String,Object>();
        welcomeMsg.put("welcome",username + "进入聊天室!!");
        welcomeMsg.put("usernames",usernames);
        //login对象转为  json格式
        String msg = gson.toJson(welcomeMsg);
        broadcast(ss, msg);
    }
    @OnClose
    public void close() {
        ss.remove(this);
        usernames.remove(username);
        Map<String,Object> logoutMsg = new HashMap<String,Object>();
        logoutMsg.put("welcome",username + "退出聊天室!!");
        logoutMsg.put("usernames",usernames);
        String msg = gson.toJson(logoutMsg);
        broadcast(ss, msg);
    }
    @OnMessage
    public void receiveMsg(Session session, String content) {
        System.out.println("收到信息啦 , 来自sid:" + session.getId());
        System.out.println("信息:" + content);
        Msg msg = gson.fromJson(content, Msg.class);
        msg.setDate(new Date().toLocaleString());
        broadcast(ss, gson.toJson(msg));
    }
    private void broadcast(Set<ChatSocket> ss, String msg) {
        for (Iterator iterator = ss.iterator(); iterator.hasNext(); ) {
            ChatSocket chat = (ChatSocket) iterator.next();
            try {
                chat.session.getBasicRemote().sendText(msg);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


相关问答

更多

java怎么实现与websocket服务器的通信

websocket服务器的通信可以用tomcat-api来实现的, 以前做过一个简单的推送示例,2227421573帮你写好

java websocket web网页聊天怎么实现

websocket 是反向推送的一种类型 聊天需要实时性高,在A第一次发送信息给B的时候需要建立websocket的连接,A向B发送信息就通过websocket完成。 A如果关闭窗口则websocket断开连接

socket.io聊天室,做服务器集群会有问题吗

两个问题要注意 配置 nginx 支持 websocket 注意 socket.io 会话保持方面的坑。 你要想办法把消息共享这方面的逻辑移出 node 进程,放在一个共享的地方,比如接上 redis 之类的

socket.io聊天室,做服务器集群会有问题吗

两个问题要注意 配置 nginx 支持 websocket 注意 socket.io 会话保持方面的坑。 你要想办法把消息共享这方面的逻辑移出 node 进程,放在一个共享的地方,比如接上 redis 之类的

csdn java聊天室私人对话程序

有一种方式是通过脚本语言在客户端通过判断消息的一些标识,选择性的显示消息,这种方式实现起来简单但是不够安全,看什么场合用了。

WebSocket教程

相关文章

更多

最近更新

更多