基于webSocket实现的一对一在线聊天系统
来源:互联网 发布:java 接口变量 编辑:程序博客网 时间:2024/04/30 08:40
简单介绍一下websocket(来自网络):随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。
环境:
tomcat7.0.70(tomcat需要在7.0.27以上才能支持)
jdk1.8.0_92
eclipse
重要的类和注解:
CopyOnWriteArraySet 多对多聊天
ConcurrentHashMap 一对一聊天
Session(websocket包下的)
@ServerEndpoint()
@OnOpen
@OnClose
@OnMessage
@OnError
@PathParam
后台代码实现:
package com.bz.chat;import java.io.IOException;import java.util.HashMap;import java.util.Map;import java.util.concurrent.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。无需在web.xml中配置。//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() + "");}}webSocketMap.remove(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.parseInt(jsonOject.getString("sendUser"));toUser = Integer.parseInt(jsonOject.getString("toUser"));message = jsonOject.getString("message");message = "来自:" + sendUser + "用户发给" + toUser + "用户的信息:" + message + " \r\n";// 得到接收人Chat user = webSocketMap.get(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")){this.session.getBasicRemote().sendText("count:" + message);//在jsp判断是否包含count}else{this.session.getBasicRemote().sendText(message);//提供阻塞式的消息发送方式// this.session.getAsyncRemote().sendText(message);//提供非阻塞式的消息传输方式。}}// 获得当前在线人数public static synchronized int getOnlineCount() {return onLineCount;}// 新用户public static synchronized void addOnlineCount() {Chat.onLineCount++;}// 移除退出用户public static synchronized void subOnlineCount() {Chat.onLineCount--;}}
前端页面实现:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!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>webScocket一对一聊天</title><script type="text/javascript"> var websocket = null;function login(){if('WebSocket' in window){ var sendUser = document.getElementById("sendUser").value; document.getElementById("sendUser").disabled = true;websocket = new WebSocket("ws://localhost:8080/websocket/chatDemo/" + sendUser); }else{ alert('Not support websocket') }//连接发生错误的回调方法 websocket.onerror = function(){ document.getElementById('status').innerHTML="error"; }; //连接成功建立的回调方法 websocket.onopen = function(event){ document.getElementById('status').innerHTML="连接服务器成功"; } //接收到消息的回调方法 websocket.onmessage = function(event){ //判断分割是统计人数还是显示消息 if(event.data.indexOf("count")>-1){ var msg = event.data; var data = msg.split(":"); document.getElementById('count').innerHTML=data[1]; }else{ setMessageInnerHTML(event.data); } } //连接关闭的回调方法 websocket.onclose = function(){ document.getElementById('status').innerHTML="连接被成功关闭"; } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function(){ websocket.close(); }} //将消息显示在网页上 function setMessageInnerHTML(innerHTML){ document.getElementById('showMsg').innerHTML += innerHTML; } //关闭连接 function closeWebSocket(){ websocket.close(); } //发送消息 function send(){ var sendUser = document.getElementById("sendUser").value; var toUser = document.getElementById("toUser").value; var message = document.getElementById("message").value; var jsonMsg = {"sendUser":sendUser,"toUser":toUser,"message":message} websocket.send(JSON.stringify(jsonMsg)); document.getElementById('showMsg').innerHTML += message; }</script></head><body>账 号:<input type="text" name="sendUser" id="sendUser"/> <input type="button" id="login" value="登录" onclick="login()"/> <input type="button" onclick="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="发送" onclick="send()"/> <input type="button" value="关闭" onclick="closeWebSocket()"/></body></html>
0 0
- 基于webSocket实现的一对一在线聊天系统
- tornado实现基于websocket的好友一对一聊天功能
- 基于websocket+java聊天系统的实现
- 基于WebSocket的聊天系统
- 基于HTML5 WebSocket,JavaEE 7在线聊天系统
- 基于webSocket的多人聊天系统
- php基于websocket实现的在线聊天室
- 基于JavaSE的在线聊天系统
- 基于Tomcate、java、websocket 简单在线聊天
- 基于(ssm,websocket,mysql)开发的web聊天系统
- 使用.net和jquery实现一对一的网页聊天系统
- Spring -websocket实现简易在线聊天
- JavaWeb--使用Websocket实现在线聊天功能
- tomcat websocket 实现网页在线即时聊天
- 一对一聊天程序的实现
- Web 实现在线聊天的系统 强烈推荐
- Java websocket + redis 实现多人单聊天室,多人多聊天室, 一对一聊天
- 基于Node.js + socket.io实现WebSocket的聊天DEMO
- bzoj3158 千钧一发
- 数据结构-->队列的链式实现 ADT
- 获取当前计算机所有性能计数器
- markdown的11种简单语法
- Activity的findViewById()和View的findViewById()
- 基于webSocket实现的一对一在线聊天系统
- Number of Islands
- 不同BIOS下的U盘启动设置方法
- com/android/dx/command/dexer/Main : Unsupported major.minor version 52.0
- Exchange 2010 PS之获取移动设备相关信息!
- c语言scanf返回值
- GCC/G++编译原理分析
- HDU 2187 悼念512汶川大地震遇难同胞——老人是真饿了
- VC6.0向VC2010过渡要做的调整