package com.bz.chat;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import urrent.ConcurrentHashMap;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
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;
import net.sf.json.JSONObject;
//该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。类似Servlet的注解mapping。无需在l中配置。
//chatDemo:表示访问的具体url。{sendUser}:表示在url上的参数
@ServerEndpoint("/chatDemo/{sendUser}")
public class Chat{// 用户在线数private static int onLineCount = 0;// 当前的websocket对象private static ConcurrentHashMap<Integer, Chat> webSocketMap = new ConcurrentHashMap<Integer, Chat>();// 当前会话,属于websocket的sessionprivate Session session;// 聊天信息private Integer sendUser;// 当前用户private Integer toUser;// 接收人private String message;// 聊天信息/*** 连接建立成功调用的方法* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据* @PathParam("sendUser") 表示可以在访问的时候带上参数,参数:sendUser为 @ServerEndpoint("/chatDemo/{sendUser}")* @throws IOException*/@OnOpenpublic void onOpen(@PathParam("sendUser") Integer sendUser,Session session) throws IOException {this.sendUser = sendUser;this.session = session;addOnlineCount();System.out.println("有新连接加入!当前在线人数为" + getOnlineCount() + " 当前session是" + session.hashCode());webSocketMap.put(sendUser, this);//当前用户的websocket// 刷新在线人数for (Chat chat : webSocketMap.values()) {//使用if判断是要统计人数还是发送消息chat.sendMessage("count",getOnlineCount() + "");}}/*** 连接关闭所调用的方法* * @return* @throws IOException */@OnClosepublic void onClose() throws IOException {// 在线数减1subOnlineCount();for (Chat chat : webSocketMap.values()) {//说明当前的session已经被关闭if(chat.session != this.session){chat.sendMessage("count", getOnlineCount() + "");}}ve(sendUser);System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());}/*** 收到客户端的消息后所调用的方法* * @param message 客户端发送过来的消息* @param session 可选的参数,同上* @throws IOException*/@OnMessagepublic void onMessage(String jsonMsg, Session session) throws IOException {JSONObject jsonOject = JSONObject.fromObject(jsonMsg);sendUser = Integer.String("sendUser"));toUser = Integer.String("toUser"));message = String("message");message = "来自:" + sendUser + "用户发给" + toUser + "用户的信息:" + message + " rn";// 得到接收人Chat user = (toUser);if (user == null) {//如果接收人不存在则保持到数据库System.out.println("信息已保存到数据库");return;}user.sendMessage("send",message);}/*** 发成错误所调用的方法* @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {System.out.println("发生错误");error.printStackTrace();}/*** 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。* @param type 根据类型判断是要进行在线人数统计还是发送消息 count:人数统计 send:发送消息* @param message* @param receive* @throws IOException*/public void sendMessage(String type,String message) throws IOException {if(type.equals("count")){BasicRemote().sendText("count:" + message);//在jsp判断是否包含count}else{BasicRemote().sendText(message);//提供阻塞式的消息发送方式// AsyncRemote().sendText(message);//提供非阻塞式的消息传输方式。}}// 获得当前在线人数public static synchronized int getOnlineCount() {return onLineCount;}// 新用户public static synchronized void addOnlineCount() {LineCount++;}// 移除退出用户public static synchronized void subOnlineCount() {LineCount--;}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ".dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>webScocket一对一聊天</title><script type="text/javascript">var websocket = null;function login(){if('WebSocket' in window){var sendUser = ElementById("sendUser").ElementById("sendUser").disabled = true;websocket = new WebSocket("ws://localhost:8080/websocket/chatDemo/" + sendUser);}else{alert('Not support websocket')}//连接发生错误的回调方法r = function(){ElementById('status').innerHTML="error";};//连接成功建立的回调方法pen = function(event){ElementById('status').innerHTML="连接服务器成功";}//接收到消息的回调方法ssage = function(event){//判断分割是统计人数还是显示消息if(event.data.indexOf("count")>-1){var msg = event.data;var data = msg.split(":");ElementById('count').innerHTML=data[1];}else{setMessageInnerHTML(event.data);}}//连接关闭的回调方法lose = function(){ElementById('status').innerHTML="连接被成功关闭";}//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。beforeunload = function(){websocket.close();}}//将消息显示在网页上function setMessageInnerHTML(innerHTML){ElementById('showMsg').innerHTML += innerHTML;}//关闭连接function closeWebSocket(){websocket.close();}//发送消息function send(){var sendUser = ElementById("sendUser").value;var toUser = ElementById("toUser").value;var message = ElementById("message").value;var jsonMsg = {"sendUser":sendUser,"toUser":toUser,"message":message}websocket.send(JSON.stringify(jsonMsg));ElementById('showMsg').innerHTML += message;}</script>
</head>
<body>账 号:<input type="text" name="sendUser" id="sendUser"/> <input type="button" id="login" value="登录" οnclick="login()"/> <input type="button" οnclick="closeWebSocket()" value="退出"/> 在线人数:<font id="count"></font> 连接状态:<font id="status"></font><br/>接收人:<input type="text" name="toUser" id="toUser"/><br/>消息框:<br/><textarea rows="5" cols="5" id="showMsg" name="showMsg" disabled="disabled" style="width: 302px; height: 111px; "></textarea><br/><textarea rows="5" cols="5" id="message" name="sendMsg" style="width: 302px; height: 111px; "></textarea><br/><input type="button" value="发送" οnclick="send()"/> <input type="button" value="关闭" οnclick="closeWebSocket()"/>
</body>
</html>
本文发布于:2024-02-01 10:12:37,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170675355735909.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |