利用websocket实现群聊以及单聊

  • 项目结构
  • 实现代码
  • 运行截图

在这里提供一下思路,正常情况下我们登陆进去之后就应该打开一个ws连接,以便和服务器进行通信,将打开的管道用一个set容器进行存储,并将用户名或者其他能唯一标示用户的字段作为key,把与之对应的管道作为value存储到一个map集合中。
那么怎么实现广播的方法呢?其实很简单,这需要对set容器中的每一个管道进行遍历并执sendText()方法,就可以将消息传递给了集合中每个管道(前提是在每个用户进行登陆时将用户存储到一个集合中)。
接下来首先实现群聊,通过jquery获得输入框的内容,然后通过onmessage()方法向后端传递消息,在调用广播方法就可以实现群聊了。
接下来就是单聊,单聊的实现原理就是得到被单聊的人的用户名,然后在map集合中的得到与之对应的管道,然后调用sendText()方法就可以将消息发送给对应的人了。
话不多说,直接上图上代码

项目结构

实现代码

DemoConfig.java

import java.util.Set;import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;public class DemoConfig implements ServerApplicationConfig {@Overridepublic Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scan) {// TODO Auto-generated method stubSystem.out.println("config................"+scan.size());//可以提供过滤作用return scan;}@Overridepublic Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> arg0) {// TODO Auto-generated method stubreturn null;}}

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>Insert title here</title>
</head>
<body>
<form action="LoginServlet">姓名:<input id="username" name="username" /><input type="submit" />
</form>
</body>
</html>

ChatRoom.jsp

<%@page import="java.io.PrintWriter"%>
<%@ 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>Insert title here</title><script type="text/javascript" src="jquery-1.4.2.min.js"></script><script type="text/javascript">var username="${sessionScope.username}";var ws;//一个ws对象就是一个管道var target="ws://localhost:8080/web_war_exploded/chatSocket?username="+username;window.onload=function(){//登录进入ChatRoom就打开socket通道if ('WebSocket' in window) {ws = new WebSocket(target);} else if ('MozWebSocket' in window) {ws = new MozWebSocket(target);} else {alert('WebSocket is not supported by this browser.');return;}ws.onmessage=function(event){eval("var msg="+event.data+";");if(undefined!=msg.welcome)$("#content").append(msg.welcome+"<br/>");if(undefined!=msg.usernames){$("#userList").html("");$(msg.usernames).each(function(){$("#userList").append("<input  type=checkbox  value='"+this+"'/>"+ this + "<br/>");});}if(undefined!=content){$("#content").append(msg.content+"<br/>");console.info(msg);}}}function subSend() {//判断是否选中var ss=$("#userList :checked");var val = $("#msg").val();console.info(ss.size());//如果未选中var obj=null;if(ss.size()==0){var obj={msg:val,type:1 //1广播 2单聊}}else {var to = $("#userList :checked").val();obj={to:to,msg:val,type:2 //1广播 2单聊}}var str = JSON.stringify(obj);/* $("msg").val("");var obj={to:to,msg:val,type:1 //1广播 2单聊} */ws.send(str);}</script>
</head>
<body>
<div id="container" style="border:1px solid black;width:400px;height:400px;float:left;"><div id="content" style="height:350px;"></div>
</div>
<div style="border-top:1px solid black;width:400px;height:50px;"><input id="msg" /><button onclick="subSend();">send</button>
</div><div id="userList" style="border:1px solid black;width:400px;height:400px;float:left;">
</div>
</body>
</html>

LoginServlet.java

package com.hys.servlet;import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** Servlet implementation class LoginServlet*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {private static final long serialVersionUID = 1L;/*** @see HttpServlet#HttpServlet()*/public LoginServlet() {super();// TODO Auto-generated constructor stub}/*** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubrequest.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");String username = request.getParameter("username");request.getSession().setAttribute("username", username);/*System.out.println(username);*/response.sendRedirect("ChatRoom.jsp");}/*** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)*/protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}

ChatSocket.java

package com.hys.socket;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;import com.google.gson.Gson;
import com.hys.vo.ContentVo;
import com.hys.vo.Message;import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
@ServerEndpoint(value = "/chatSocket")
public class ChatSocket {
private String username;
private Session session;
private static Map<String, Session> map=new HashMap<String, Session>();/*将管道与用户名绑定*/
private  static  Set<ChatSocket>  sockets=new HashSet<ChatSocket>();/*管道道的集合*/
private static List<String> names = new ArrayList<String>();/*用户的集合*/
private  Gson gson = new Gson();@OnOpenpublic void open(Session session) {//当前的websocket的session不是之前的session//获取username//将当前的管道加入到管道的集合中去this.session = session;this.sockets.add(this);//将当前的username与session绑定String queryname = session.getQueryString();/*System.out.println(queryname);*/username=queryname.split("=")[1];this.names.add(username);this.map.put(this.username, this.session);/*System.out.println(username);*/String msg = "欢迎"+this.username+"进入聊天室";Message message=new Message();message.setWelcome(msg);message.setUsernames(this.names);this.broadcast(sockets,message.toJson());}@OnClosepublic void close(Session session) {this.sockets.remove(this);this.names.remove(this.username);String msg = this.username+"离开聊天室";Message message=new Message();message.setWelcome(msg);message.setUsernames(this.names);broadcast(sockets,message.toJson());}
//    private static Gson gson=new Gson();@OnMessagepublic void onmessage(Session session,String json) {ContentVo vo=gson.fromJson(json, ContentVo.class);if(vo.getType()==1) {//广播Message message=new Message();message.setContent(this.username, vo.getMsg());this.broadcast(sockets,message.toJson());}else {//单聊//单聊过程与广播类似,/*分析前台传过来的消息的type如果是2的话就在map(存放的是key是用户名,value是socket)中通过getTo来取得接收信息的socket并通过to_session.getBasicRemote().sendText(gson.toJson(message))将消息传递给前台*//*举个不太恰当的例子,我想将一个苹果(消息)放到小明的冰箱(小明的前端页面),然后就我又不想动,我就想找小明然后我就喊小明的名字,小明(相当于服务器)听到我喊他的名字(从map集合中找到对应的session)然后小明就将苹果放入到了他的冰箱(对应的session调用sendText()方法传递消息)放到冰箱里(前台)* */String to=vo.getTo();Session to_session = this.map.get(to);System.out.println(to);System.out.println(to_session);Message message=new Message();message.setContent(this.username, vo.getMsg());try {to_session.getBasicRemote().sendText(gson.toJson(message));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}//广播消息
public void broadcast(Set<ChatSocket>sockets ,String msg){//遍历当前所有的连接管道,将通知信息发送给每一个管道for(ChatSocket socket : sockets){try {//通过session发送信息socket.session.getBasicRemote().sendText(msg);} catch (IOException e) {e.printStackTrace();}}
}
}

ContentVo.java

package com.hys.vo;public class ContentVo {
private String to;
private String msg;
private Integer type;
public String getTo() {return to;
}
public void setTo(String to) {this.to = to;
}
public String getMsg() {return msg;
}
public void setMsg(String msg) {this.msg = msg;
}
public Integer getType() {return type;
}
public void setType(Integer type) {this.type = type;
}
}

Message.java

package com.hys.vo;import java.util.Date;
import java.util.List;import com.google.gson.Gson;public class Message {
private String welcome;
private List<String> usernames;
private String content;
public String getContent() {return content;
}
public void setContent(String content) {this.content = content;
}public void setContent(String name,String msg) {this.content = name+""+new Date().toLocaleString()+":<br/>"+msg+":<br/>";
}public String getWelcome() {return welcome;
}
public void setWelcome(String welcome) {this.welcome = welcome;
}
public List<String> getUsernames() {return usernames;
}
public void setUsernames(List<String> usernames) {this.usernames = usernames;
}
public String toJson() {return gson.toJson(this);
} public static Gson gson=new Gson();
}

运行截图




##注意
如果使用eclipse的话,可以建立相应的目录结构将代码粘贴进去,导入jar包即可

利用websocket实现群聊以及单聊相关推荐

  1. springboot+websocket构建在线聊天室(群聊+单聊)

    系列导读: 1.springboot+websocket构建在线聊天室(群聊+单聊) 2.Spring Boot WebSocket:单聊(实现思路) 3.Websocket Stomp+Rabbit ...

  2. Android 融云单聊与群聊消息免打扰功能设置与消息删除功能实现

    一.设置群聊与单聊消息免打扰功能: 1.下面直接进入逻辑代码: 实现监听事件: /*** 设置会话列表界面操作的监听器.*/RongIM.setConversationListBehaviorList ...

  3. websocket 群/单聊 基础

    websocket 介绍 1.用户A 给 用户B 发送一条消息 问 用户B 多久可以收到 用户A 的消息电子邮件 - 可能是 一周期的时间 及时性很差传达室大爷 - 消息托付 及时性很差即时通讯 - ...

  4. (3)websocket实现单聊和群聊

    1 资源下载地址  http://download.csdn.net/detail/jianfpeng241241/9325049 2  群聊图 2.1 zhangsan 发给所有人的图 2.2 发送 ...

  5. websocket 群聊和单聊实现简单在线客服

    根据菜鸟教程上的解释: WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间 ...

  6. Springboot+netty+websocket 实现单聊群聊及用户鉴权

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.配置 二.Netty服务 1. WsServer构建 2. ChannelInitializer构建 3. 自定义 ...

  7. vue+websokect实现实时聊天,可单聊、可群聊(一)

    效果图 效果网站链接,安全性不符合实际上线使用,仅供学习交流 https://livequeen.top 效果小程序二维码 (需现在web端获取账号)          思路 一个实时聊天功能 第一, ...

  8. Flask+geventwebsocket实现群聊与单聊功能

    Flask+WebSocket 实现群聊与单聊功能 群聊 py文件 from flask import Flask ,request,render_template from geventwebsoc ...

  9. SpringBoot + Vue 实现基于 WebSocket 的聊天室(单聊)

    前言 在前一篇文章SpringBoot 集成 STOMP 实现一对一聊天的两种方法中简单介绍了如何利用 STOMP 实现单聊,本文则将以一个比较完整的示例展示实际应用,不过本文并未使用 STOMP,而 ...

最新文章

  1. DOM和Diff算法你应该知道的那些事,快收藏!
  2. 【Java基础】Java中的持久属性集Properties
  3. Linux 临时表空间满了,Temporary表空间100%解决方案
  4. Leetcode--714. 买卖股票的最佳时间含手续费
  5. url中能出现的字符_网站URL配置4个技巧,轻松获得更多流量
  6. 利用matlab程序分别设计一正弦型信号_ARM Mbed数字信号处理
  7. mvp内粗泄露问题_如何在一小时内启动MVP服务器
  8. android的应用组件,跟我学android-Android应用基本组件介绍(五)
  9. STM32 编码器的CUBEMX的使用
  10. 初入c++ (八) c++输入和输出
  11. 跑赢业务的同时如何实现技术成长? | 凌云时刻
  12. 【转】el-cascade设置默认值遇到的坑!
  13. CHIL-SQL-LEFT JOIN 关键字
  14. 皮皮虾如何去水印视频
  15. 助教日志_沈航软件工程评分1.2班第三周作业及总评成绩
  16. 老男孩教育运维班100台规模集群全网数据备份项目上机实战
  17. 如何解决WORD安全模式错误问题
  18. c语言错误不允许使用不完整的类型,C语言不允许使用不完整的类型报错是什么意思啊...
  19. Firefox设置谷粉搜搜为默认搜索引擎的方法
  20. vue 列表展开收起

热门文章

  1. 下载IE6的完整版的‘方法
  2. opencv柱面投影,C语言实现
  3. 20150311,微软3月11日发布14个安全补丁
  4. 【汇编语言】Arm处理器之中断处理
  5. 基于THREEJS场景中模型局部辉光效果
  6. 全志F1C600芯片处理器介绍
  7. 因式分解结合最近邻:多层面的协同过滤模型
  8. 五分之一金融机构将从2018年开始探索加密货币交易
  9. 【小程序动画合集】10种小程序动画效果实现方法,文章太长建议收藏!
  10. java操作excel文件基础架构实现,支持2007以上版本