WebSocket简单聊天

刚学习了WebSocket ,写了一个简单的聊天功能,在这里记录一下;想学习的也可以参考。

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。

首先给出代码,运行一下看看效果:
(界面有些丑,忽略这些细节,之后再进行美化;)
index.jsp 这是登录页面,获取聊天时的昵称;

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>登录</title>
</head>
<style>
    .container{
        width: 400px;
        height: 600px;
        background: navajowhite;
        margin: 0 auto;
        text-align: center;
    }
    .pic{
        margin: 0 auto;
        width:100px;
        height: 100px;
        border-radius: 50px;
        background:gray;
    }
    #name{
        width: 200px;
        height: 50px;
        margin-top: 200px;
    }
    button{
        text-decoration: none;
        background: darkcyan;
        width: 200px;
        height: 50px;
    }
</style>
<script type="text/javascript" src="jquery/jquery-2.2.4.min.js" ></script>
<body>

<header>聊天</header>

<div class="container">
    <form action="/UserServlet"  method="post" id="login">
        <div class="pic">

        </div>
        <div class="login">
            <div class="name">
                <input type="text" name="nick" id="name"/>
            </div>
            <div>
                <!--    <a href="javascript:goChat()">登录</a>-->
                <button class="but" onclick="goChat()">登录</button>
            </div>
        </div>
    </form>
</div>
</body>
<script type="text/javascript">

    function goChat(){
        $("#login").submit();
    }


</script>

</html>

chatroom.jsp 这是聊天的页面,能看到所有用户发送的消息:

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2017/10/11 0011
  Time: 18:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<style type="text/css">
    .container{
        width: 400px;
        height: 600px;
        background: navajowhite;
        margin: 0 auto;
        text-align: center;
    }
    .message{
        width:400px;
        height: 400px;
        position: absolute;
        top:100px;
        background: indianred;

    }
    li{
        margin: 0;
        background: khaki;
        width: 300px;
        height: 20px;
        list-style:none;

    }
    .msg{
        position: absolute;
        width:400px;
        height: 50px;
        top:550px;
        background: indianred;
    }
    input[name = "msg"]{
        width: 200px;
        height: 40px;
    }
    button{
        width: 90px;
        height: 47px;
    }
</style>
<script type="text/javascript" src="jquery/jquery-2.2.4.min.js" ></script>
<body>
<div class="container">

    <div class="message">
        <ul class="list">

        </ul>
    </div>
    <% String nick = (String)request.getAttribute("nick");%>
    <div class="msg">
        <input type="text" name="msg" id="msg" value="" /><button class="send" value="">发送</button>
    </div>

</div>

</body>

<script type="text/javascript">
    var ws = null;
    if(WebSocket){
        ws = new WebSocket("ws://localhost:8080/chat");
    }else{
        alert("浏览器不支持");
    }
    ws.onopen = function(){
        ws.send("用户<%=nick%>加入聊天室");
    }

    ws.onmessage = function(event){
        showMessage(event.data);
    }

    function showMessage(msg){
        var message = $(".list");
        var html = message.html();
        html += "<li>"+msg+"</li>";
        message.html(html);
        message.scrollTop(message[0].scrollHeight);

    }

    $(".send").click(function () {
        var msg = $(this).siblings("input").val();
        ws.send("<%=nick%>说:"+msg);
        $(this).siblings("input").val("");
    })

</script>



</html>

UserServlet 用于转发用户名,之后可以用框架实现:

package com.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/UserServlet")
public class UserServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String nick = request.getParameter("nick");
        request.setAttribute("nick",nick);
        request.getRequestDispatcher("/chatroom.jsp").forward(request,response);


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}

ChatServer 聊天的服务器 用于接收发送消息

package com.websocket;


import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint("/chat")
public class ChatServer {

    private Session session;
//    private static Map<String,ChatServer> map = new HashMap(String,ChatServer);
    private static CopyOnWriteArraySet<ChatServer> servers = new CopyOnWriteArraySet<ChatServer>();

    @OnOpen
    public void onOpen(Session session){
        this.session = session;
        servers.add(this);
        System.out.println("建立连接"+session.getId());

    }
    @OnMessage
    public void onMessage(String msg){
//        try {
//            this.session.getBasicRemote().sendText(msg);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        System.out.println("接受信息:"+msg);
        //向所有的用户发送消息
        try{
            for (ChatServer server:servers){

                server.session.getBasicRemote().sendText(msg);

            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    @OnError
    public void onError(Throwable error){
        System.out.println("错误:");
        error.printStackTrace();
    }
    @OnClose
    public void onClose(){
        servers.remove(this);
    }

}

简单说明一下运行的过程:

在登录界面,输入用户名,登录, 会通过表单提交的UserServlet,UserServlet再转发到chatroom.jsp
在加载的时候,创建了一个websocket对象
ws = new WebSocket(“ws://localhost:8080/chat”);
就是这句, 这里我有一个疑惑,在IDEA中要直接写ChatServer的路径, 在Eclipse 要加上项目名;这个问题纠结了好久,还是没有答案;
找到ChatServer,如果连接成功了 ,就会执行 onopen方法 ,控制台输出对应的数据,
同样,jsp中的 ws.onopen的方法也会执行; ws.send(“用户<%=nick%>加入聊天室”); 这句就是向服务端发送了消息, 再服务端通过 onMessage 接收数据,控制台输出; 这样就可以简单的发送消息;
不过这样只能是自己看到消息 ,需要对每一个在线的用户都发送消息
private static CopyOnWriteArraySet servers = new CopyOnWriteArraySet(); 用来存储每个用户的 websocket ;

servers.add(this); 用户连接时,向set中添加一个websocket

try{
for (ChatServer server:servers){
server.session.getBasicRemote().sendText(msg);
}
}catch (IOException e){
e.printStackTrace();
}

通过遍历servers中的websocket,向每一用户发送消息,
这样, 简单的聊天 就实现了;

猜你喜欢

转载自blog.csdn.net/naihe0420/article/details/78209572