Java使用websocket实现聊天室简单功能

最近有个项目需要实现视频流的信息交换处理,但是之前一直都没有写过有关的代码,所以就想到了websocket接口。

java创建一个socket非常简单,繁琐的可能是日常的业务信息处理,下面看下一段代码:

import model.User;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by alan.luo on 2017/9/10.
 */

@ServerEndpoint(value = "/websocket2")
public class TestWebSocket {

    @OnOpen
    public void onOpen(Session session, EndpointConfig endpointConfig) {
        sendMsg(session,"Welcome back.");

        //push list.
        User user = new User();
        user.setId(Integer.parseInt(session.getId()));

        Map<String,List<String>> map = session.getRequestParameterMap();
        user.setUserName(map.get("userName").get(0));
        user.setSession(session);

        //has client come in,so server must be save the session to the application.class.
        Application.getInstance().putSession(user);
    }

    @OnMessage
    public void onMessage(Session session,String message){
        System.out.println("++++++++++:"+message);

        //if has user push message to the server.then server will each all the client and send message too.
        for (User user:Application.getInstance().getUsers()){
            sendMsg(user.getSession(),user.getUserName() + " say:"+message);
        }

    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason){
        List<User> list = Application.getInstance().getUsers();
        //pop list.
        for (int i = 0;i<list.size();i++){
            if (Integer.parseInt(session.getId()) == list.get(i).getId()){
                list.remove(i);
                Application.getInstance().setUsers(list);
                break;
            }
        }
    }

    @OnError
    public void onError(Session session, Throwable thr) {
        System.out.println("+++++++++onError"+thr.getMessage());
    }

    /**
     * send message to session.
     * @param session
     * @param message
     */
    protected void sendMsg(Session session,String message){
        System.out.println(message);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            session.getBasicRemote().sendText(message+" >"+sdf.format(new Date()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

当有客户端进入,则把客户端保存到application这个实例中,application是自定义的一个类,实现了单例,所以保存进去是最合适的,当有消息进入时,server将从application读取session list 并且遍历全部session and send the message。

Application实例的代码:

import model.User;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by alan.luo on 2017/9/10.
 */
public class Application {

    private List<User> users;
    private static Application app;

    public Application(){
        users = new ArrayList<>();
    }

    public static Application getInstance(){
        if (app == null){
            app = new Application();
        }
        return app;
    }

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }

    public void putSession(User s){
        this.users.add(s);
    }

}

User实体类的代码:

package model;

import javax.websocket.Session;

/**
 * Created by alan.luo on 2017/9/6.
 */
public class User {
    private int id;

    private String userName;

    private String userPassword;

    private Session session;

    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPasswd) {
        this.userPassword = userPasswd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", userPassword='" + userPassword + '\'' +
                '}';
    }
}

可能会有错误,那是因为需要配置一下web.xml

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/websocket2</url-pattern>
</servlet-mapping>

 

剩下的就是javascript客户端的代码了:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <p><input type="text" id="userName" value="" placeholder="输入名字进入聊天室"></p>
</div>
<div>
    <textarea rows="16" cols="40" id="content"></textarea>
</div>
<div>
    <input type="text" id="message" value="" placeholder="输入内容"/>
    <button type="button" id="send">send</button>
</div>
<div>

    <button type="button" id="connect">connect</button>
    <button type="button" id="destroy">destroy</button>
</div>
<script>

        var connect = document.getElementById("connect");
        var content = document.getElementById("content");
        var message = document.getElementById("message");
        var destroy = document.getElementById("destroy");
        var send = document.getElementById("send");
        var userName = document.getElementById("userName");
        var socket = null;

        connect.addEventListener("click",function () {
            console.log("connect")
            if(userName.value.length <= 2){
                return false;
            }
            socket = new WebSocket("ws://localhost:8080/websocket2?userName="+userName.value);

            socket.onopen = function (p1) {
                console.log("onopen",p1)
            }

            socket.onclose = function (p1) {
                console.log("onclose",p1)
            }
            socket.onerror = function (p1) {
                console.log("onerror",p1)
            }
            socket.onmessage = function (p1) {
                console.log("onmessage",p1)
                content.innerHTML = (content.innerHTML + p1.data + "\n")
            }
        });
        destroy.addEventListener("click",function () {
            console.log("destroy")
            socket.close();
        });
        send.addEventListener("click",function () {
            console.log("send")
            socket.send(message.value);
            message.value = "";
        });


</script>

</body>
</html>

最后上传一张效果图吧:

QQ截图20170910223850

Leave a Comment

 
Copyright © 2008-2021 lanxinbase.com Rights Reserved. | 粤ICP备14086738号-3 |