spring boot Java实现网页一对一 一对多实时聊天 webSocket

Java实现网页一对一 一对多实时聊天websocket

后台代码 最重要的类

package com.socket.websocket.chat;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
/**
 * websocket
 * @author CHHUANG
 */
@ServerEndpoint("/webSocket/{senderId}") // 该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。类似Servlet的注解mapping。无需在web.xml中配置。
@Component
public class WebChat {
    // 用来存放每个客户端对应的ChatAnnotation对象,实现服务端与单一客户端通信的话,使用Map来存放,其中Key可以为用户标识,hashtable比hashmap线程安全
    private static Map<String, WebChat> webSocketMap = new Hashtable();
    // 与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    /**
     * 连接建立成功调用的方法
     * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(@PathParam(value="senderId") String senderId, Session session) {
        this.session = session;
        webSocketMap.put(senderId,this);//加入map中
        System.out.println(senderId+"连接加入!当前在线人数为"+getOnlineCount());
    }
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam(value="senderId") String userId) {
        webSocketMap.remove(userId);
        System.out.println(userId+"关闭连接!当前在线人数为" + getOnlineCount());
    }
    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(@PathParam(value="senderId") String senderId, String message, Session session) {
        // 群发消息
        try {
            //将前端发送的 JSON 字符串转换为 JSON 对象
            JSONObject jsonMessge = JSON.parseObject(message);
            //获取接收者ID列表
            JSONArray list = jsonMessge.getJSONArray("userList");
            //获取发送者的聊天对象
            WebChat userMap = webSocketMap.get(senderId);
            //获取发送的消息
            String mess=jsonMessge.getString("mess");
                //为自己发送一条消息
                userMap.sendMessage(mess);
                    //遍历消息接受者列表
                for (Object receiverId : list) {
                    //获取消息接受者
                    WebChat receiver = webSocketMap.get(receiverId);
                    //调用session的发送消息方法  将消息发送到客户端
                    receiver.sendMessage(mess);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public void onError(@PathParam(value="userId") String userId, Session session, Throwable error) {
        System.out.println(userId+"发生错误");
        error.printStackTrace();
    }

    /**
     * 发送消息
     * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    /**
     * 发送文件
     * @throws IOException
     */
    public void sendFile(File file)throws IOException{
        this.session.getAsyncRemote().sendObject(file);
    }

    public static synchronized int getOnlineCount() {
        return webSocketMap.size();
    }

}

配置类

package com.socket.websocket.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        System.out.println(">>>>>>>>>>>>>>>>>启用 WebSocket");
        return new ServerEndpointExporter();
    }
}

pom.xml

<!--websocket连接需要使用到的包-->
	<dependency>
	        <groupId>javax.websocket</groupId>
	        <artifactId>javax.websocket-api</artifactId>
	        <version>1.1</version>
	        <scope>provided</scope>
	    </dependency>
	    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

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

        <!-- fastjson JSON-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.31</version>
        </dependency>

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style type="text/css">
    input#chat {
        width: 410px
    }
    #console-container {
        width: 400px;
    }

    #console {
        border: 1px solid #CCCCCC;
        border-right-color: #999999;
        border-bottom-color: #999999;
        height: 170px;
        overflow-y: scroll;
        padding: 5px;
        width: 100%;
    }

    #console p {
        padding: 0;
        margin: 0;
    }
</style>
<body>
<div>
    <p>
        <input type="text" placeholder="type and press enter to chat" id="chat" />
    </p>
    <div id="console-container">
        <div id="console"></div>
    </div>

    <script type="text/javascript">
        var Console = {};
        var mess={};
		var userList=[];
		var senderId=prompt("请输入你的账号");
        Console.log = (function(message) {
            var console = document.getElementById('console');
            var p = document.createElement('p');
            p.style.wordWrap = 'break-word';
            p.innerHTML = message;
            console.appendChild(p);
            while (console.childNodes.length > 25) {
                console.removeChild(console.firstChild);
            }
            console.scrollTop = console.scrollHeight;
        });
        var Chat = {};
        Chat.socket = null;
        Chat.connect = (function(host) {
            if ('WebSocket' in window) {
                Chat.socket = new WebSocket(host);
            } else if ('MozWebSocket' in window) {
                Chat.socket = new MozWebSocket(host);
            } else {
                Console.log('错误');
                return;
            }
            Chat.socket.onopen = function() {
                Console.log('打开连接');
                document.getElementById('chat').onkeydown = function(event) {
                    if (event.keyCode == 13) {
                        Chat.sendMessage();
                    }
                };
            };
            Chat.socket.onclose = function() {
                document.getElementById('chat').onkeydown = null;
                Console.log('关闭.');
            };
            Chat.socket.onmessage = function(message) {
                Console.log(message.data);
            };
        });
        Chat.initialize = function() {
            Chat.connect('ws://127.0.0.1:8080/webSocket/'+senderId);
        };
        Chat.sendMessage = (function() {
			
            var message = document.getElementById('chat').value;
			
			var receiverIds=prompt("请输入接收者账号用逗号分隔");
			
			userList=receiverIds.split(",");
			
			mess.userList=userList;
			
			mess.mess=message;
			
			var strmee=JSON.stringify(mess)
			
            if (message != '') {
				//发送
                Chat.socket.send(strmee);
				//清空输入框
                document.getElementById('chat').value='';
            }
        });
        Chat.initialize();
    </script>
</div>
</body>
</html>

第一次发帖…复制别人的稍微做了修改 可以把html打开多个页面进行测试
用的是spring boot 有条件的可以在 我的主页去找源码
没条件的去这里 https://pan.baidu.com/s/1DcnrdiSlh1CQAe9SUg5rcg
取件码:hhva

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值