【java】webSocket(二)——实时聊天
来源:互联网 发布:淘宝上比较好吃的零食 编辑:程序博客网 时间:2024/06/06 06:44
一、前言
在上一篇博客中,小编简单向大家介绍了一下websocket,在这篇博客中小编将通过一个聊天实例来展示一下websocket是如何使用的。
二、资料准备
2.1 环境要求
- JDK版本在1.7以上
注:小编刚开始的时候使用的是JDK 1.6 无法运行,原因是websocket是j2ee7规范引入,只要使用支持其标准的服务器就可以运行,所以要在JDK1.7的环境上运行。
2.2 jar包的准备
我们需要三个jar包:
tomcat7-websocket.jar
websocket-api.jar
gson-2.2.4.jar
简单介绍:前两个jar包是在tomcat7及以上版本的lib目录下获得的。主要是封装了websocket的API方法类以及实现了其中的方法。gson.jar是一个操作json的jar包。我们用他把字段转换成为json字符串。
三、实战操作
关于实时聊天的需求是这样的,我们有一个登录的页面,输入用户名后,点击登录就可以跳转到聊天窗口。在聊天窗口上就会显示“欢迎XXX来到聊天室~”以及在线的列表中显示在线的人的人名。用户可以发送消息,可以群发,也可以单聊。
3.1 建立web项目
建立一个名字为chatTest的web项目,把上文提到的jar包导入WEB-INF/lib目录下。
3.2 编写启动类
在src下建立名为com.dmsd.config的包,在此包中建立DemoConfig类,实现ServerApplicationConfig 接口。
ServerApplicationConfig 是websocket的核心配置类。会在项目启动的时候,自动执行。
实现ServerApplicationConfig后,会有两个方法getAnnotatedEndpointClasses和getEndpointConfigs。
getAnnotatedEndpointClasses会扫描src下所有带有@ServerEndPoint注解的类。
getEndpointConfigs会获取所有以接口方式配置的websocket类
DemoConfig :
package com.dmsd.config;import java.util.Set;import javax.websocket.Endpoint;import javax.websocket.server.ServerApplicationConfig;import javax.websocket.server.ServerEndpointConfig;public class DemoConfig implements ServerApplicationConfig { public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scan) { System.out.println("endPoint扫描到的数量:"+scan.size()); //返回提供了过滤的作用 return scan; } public Set<ServerEndpointConfig> getEndpointConfigs( Set<Class<? extends Endpoint>> arg0) { return null; }}
3.3 用户登录
编写用户登录jsp:
用户登录后,就会提交表单,调用后台的LoginServlet。
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>登录</title> <script type="text/javascript" src="js/jquery-1.4.4.min.js"></script> </head> <body> <form action="LoginServlet" method="post" name="ff"> name:<input name="username"/><br> <input type="submit"/> </form> </body></html>
LoginServlet :
package com.dmsd.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * Servlet implementation class 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 { } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); //获取登录提交表单中的用户姓名信息 String username = request.getParameter("username"); //把用户姓名存储到session中 request.getSession().setAttribute("username",username); //重定向到chat.jsp response.sendRedirect("chat.jsp"); }}
3.4 事件操作
当跳转到chat.jsp页面的时候,会加载其中的js文件,js中会开启一个通信管道。页面加载判断是否已经开启了这个通道,如果没有开启,就开启。当管道开启的时候就会触发onopen事件。触发的方法在ChatSocket类中。
chat.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>聊天室</title><script type="text/javascript" src="js/jquery-1.4.4.min.js"></script><script> var ws; //一个ws对象就是一个通信管道!!,只要不关浏览器,不关闭服务器就一直开着 var target="ws://localhost:8080/chatTest/chatSocket?username=${sessionScope.username}"; $().ready(function connect() { //页面加载判断是否已经开启了target这个通道,如果没有开启,就开启 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 result="+event.data); if(result.alert!=undefined){ $("#content").append(result.alert+"<br/>"); } if(result.names!=undefined){ $("#userList").html(""); $(result.names).each(function(){ $("#userList").append(this+"<br/>"); }); } if(result.from!=undefined){ $("#content").append(result.from+" "+result.date+ " 说:<br/>"+result.sendMsg+"<br/>"); } }; }); //点击发送消息触发事件 function send(){ var msg = $("#msg").val(); ws.send(msg); $("#msg").val(""); } </script></head><body> <h3>欢迎 ${sessionScope.username} 使用本系统!!</h3> <div id="content" style=" border: 1px solid black; width: 400px; height: 300px; float: left; "></div> <div id="userList" style=" border: 1px solid black; width: 100px; height: 300px; float:left; "></div> <div style="clear: both;"> <input id="msg" /> <button onclick="send();">send</button> </div></body></html>
在ChatSocket类中,可以把他理解为一个事件操作类,需要添加@ServerEndpoint的注解,这样当系统跑起来的时候,会监控它,来判断是否有推送消息,退出系统,登录系统的操作等等,这样就达到了一个实时的效果。
在这个类中有以下几种事件:
@OnOpen 开启通道的时候触发
@OnClose 关闭通道的时候触发
@OnMessage 客户端发送数据的时候触发
ChatSocket :
package com.dmsd.socket;import java.io.IOException;import java.util.ArrayList;import java.util.Date;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Set;import javax.websocket.OnClose;import javax.websocket.OnMessage;import javax.websocket.OnOpen;import javax.websocket.Session;import javax.websocket.server.ServerEndpoint;import com.dmsd.vo.Message;import com.google.gson.Gson;@ServerEndpoint("/chatSocket")public class ChatSocket { private static Set<ChatSocket> sockets=new HashSet<ChatSocket>(); private static List<String> nameList=new ArrayList<String>(); private Session session; private String username; private Gson gson=new Gson(); //只要有人连接这个服务,就会打开,执行下面的方法。 @OnOpen public void open(Session session){ //一个session就代表一个通信会话 System.out.println("sessionid:"+session.getId()+"通道开启了。。。。"); //把session添加到容器中 this.session=session; sockets.add(this); //getQueryString把url中?后面的所有的串儿都取出来 String QueryString = session.getQueryString(); System.out.println(QueryString); //获取用户名 this.username = QueryString.substring(QueryString.indexOf("=")+1); nameList.add(username); Message message = new Message(); message.setAlert(username+"进入聊天室!!"); message.setNames(nameList) ; broadcast(sockets, gson.toJson(message) ); } //退出 @OnClose public void close(Session session){ //1.清理退出的session sockets.remove(this); //2.清理列表用户名 nameList.remove(this.username); //3.更新消息信息 Message message=new Message(); message.setAlert(this.username+"退出聊天室!!"); message.setNames(nameList); //4.广播消息信息 broadcast(sockets, gson.toJson(message)); } //收 @OnMessage /** * * @param session * @param msg 从客户端接收的消息 */ public void message(Session session,String msg){ //接收消息 Message message=new Message(); message.setSendMsg(msg); message.setFrom(this.username); message.setDate(new Date().toString()); broadcast(sockets, gson.toJson(message)); } /** * 广播消息 * @param ss 用户session * @param msg 广播消息 */ public void broadcast(Set<ChatSocket> ss ,String msg ){ for (Iterator iterator = ss.iterator(); iterator.hasNext();) { ChatSocket chatSocket = (ChatSocket) iterator.next(); try { chatSocket.session.getBasicRemote().sendText(msg); } catch (IOException e) { e.printStackTrace(); } } }}
四、小结
通过这次练习,小编把websocket的四个步骤算是搞明白了,知道了具体处理的流程,操作也比较方便了。以后会更好的了解了websocket的发展,以及数据的传输。
- 【java】webSocket(二)——实时聊天
- WebSocket ——多人实时聊天
- 实时聊天APP(websocket+hybridAPP)
- vue+websocket+express+mongodb实战项目(实时聊天)(二)
- Java实现WebSocket聊天
- Spring+WebSocket+SockJS实现实时聊天
- 用websocket爬去来疯的实时聊天数据
- PHP+swoole+websocket聊天实时通信
- WebSocket实现多人实时聊天
- 网页实时聊天之PHP实现websocket
- 使用WebSocket实现多人实时聊天
- 网页实时聊天之PHP实现websocket
- 使用WebSocket实现多人实时聊天
- websocket(聊天功能)
- websocket点对点聊天java实例
- Web实时通讯——轮询、WebSocket
- vue+websocket+express+mongodb实战项目(实时聊天)(一)
- 写一个Tomcat+Okhttp实现的聊天websocket聊天框架(二)--完成私聊功能
- ViewPager源码分析
- VS开发Linux程序(VisualGDB)
- 2017暑期实习招聘-产品经理-腾讯T大专场(一站式面试)
- 视频编解码基础
- python TypeError: can't pickle _thread.RLock objects
- 【java】webSocket(二)——实时聊天
- [一起学Hive]之九-Hive的查询语句SELECT
- The GNU Build System
- Java并发集合的实现原理
- vue全家桶系列2-webpack+es6
- Oracle查询数据表结构(字段,类型,大小,备注)
- 1027 大数乘法
- 互联网风雨十年,我所经历的技术变迁
- Merged Manifest官方文档