WebSocket
2016-07-09 11:29
190 查看
WebSocket简介
WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-duplex)。一开始的握手需要借助HTTP请求完成.WebSocket运行原理
在 WebSocket API,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。WebSocket两大好处
Header 互相沟通的Header是很小的-大概只有 2 Bytes Server Push 服务器的推送,服务器不再被动的接收到浏览器的request之后才返回数据,而是在有新数据时就主动推送给浏览器。
WebSocket的应用场景
社交聊天、弹幕、多玩家游戏、协同编辑、股票基金实时报价、体育实况更新、视频会议/聊天、基于位置的应用、在线教育、智能家居等需要高实时的场景注:webSocket服务端需要Tomcat7+ JDK1.7+ 支持
Gson简介
GSON是Google开发的Java API,用于转换Java对象和Json对象 gson和其他现有java json类库最大的不同时gson需要序列化的实体类不需要使用annotation来标识需要序列化的字段,同时gson又可以 通过使用annotation来灵活配置需要序列化的字段。在Java开发中,有时需要保存一个数据结构成字符串,可能你会考虑用Json,但是当 Json字符串转换成Java对象时,转换成的是JsonObject,并不是你想要的Class类型的对象。gson网址:http://blog.csdn.net/qxs965266509/article/details/427746
创建一个web项目
导入jar包
创建webSocket启动文件
创建登录页面
创建登录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;
/**
* 类描述:用户登录
*/
@WebServlet(“/LoginServlet”)
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
//前台获取登录名
String username = request.getParameter(“username”);
//将登录名放入session中
request.getSession().setAttribute(“username”, username);
//跳转到聊天页面
response.sendRedirect(“chat.jsp”);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
doGet(request, response);
}
创建聊天页面
<%@ 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="<%=request.getContextPath()%>/jquery/jquery.min.js"></script> <script type="text/javascript"> //获取用户名 var username = "${sessionScope.username}"; //一个ws对象就是一个通信管道 var ws; //服务器端EndPoint的URL var target="ws://169.254.187.126:8080/chat/chatSocket?username="+username; window.onload=function(){ //进入聊天页面,就打开socket通道 // 判断浏览器是IE还是火狐 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){ //将gson转成字符串 eval("var msg="+event.data+";"); //进入聊天室的欢迎语 if(undefined!=msg.welcome){ $("#content").append(msg.welcome) } //用户列表 if(undefined!=msg.usernames){ $("#userList").html(""); $(msg.usernames).each(function(){ $("#userList").append("<input type='checkbox' value='"+this+"'>"+this+"<br/>") }) } //服务端 发送到客户端的内容 if(undefined!=msg.content){ $("#content").append(msg.content) } } } //发送方法 function subSend(){ var ss = $("#userList :checked"); var msg = $("#msg").val(); var obj = null; if(ss.size()==0){ obj={ msg:msg, type:1 //1 广播 2 单聊 } }else{ var chatToWho = $("#userList :checked").val(); obj={ chatToWho:chatToWho, msg:msg, type:2 //1 广播 2 单聊 } } //将js对象转成json串 var str = JSON.stringify(obj); ws.send(str); $("#msg").val(""); } //退出方法 function exit(){ location.href="<%=request.getContextPath()%>/login.jsp"; } </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 style="border-top:1px solid black; width:400px; height:50px;"> <input id="msg"/><button onclick="subSend();">发送</button> <button onclick="exit();">退出</button> </div> </div> <div id="userList" style="border:1px solid black; width:100px; height:400px; float:left;"></div> </body> </html>
创建Message实体类
创建Content实体类
创建WebSocket服务端
package com.ws.socket; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import com.google.gson.Gson; import com.ws.bean.Content; import com.ws.bean.Message; /** * 类描述:聊天室 * 日期: 2016年6月21日 下午9:17:37 */ @ServerEndpoint("/chatSocket") public class ChatSocket { //用户名 private String username; //session集合 private static List<Session> sessions = new ArrayList<>(); //用户列表集合 private static List<String> names = new ArrayList<String>(); //用户名与session的Map private static Map<String,Session> map = new HashMap<String,Session>(); /** * * 方法描述:进入聊天室 * 日 期:2016年6月21日 下午9:08:57 * @throws UnsupportedEncodingException */ @OnOpen public void open(Session session) throws UnsupportedEncodingException{ //当前websocket的session对象,不是servlet的session,这里的一个session代表一个通信会话! String queryString = session.getQueryString(); //获取当前登录的用户名 username = queryString.split("=")[1]; //将用户名放入用户列表集合 this.names.add(username); //将当前session放入session集合 this.sessions.add(session); //将用户名和对应session放入map中 map.put(username, session); //进入聊天室欢迎语 String msg = "欢迎"+this.username+"进入聊天室!!<br/>"; //创建message对象 Message message = new Message(); message.setWelcome(msg); message.setUsernames(this.names); //广播 this.broadcast(sessions, message.toJson()); } //创建Gson对象 private static Gson gson = new Gson(); /** * * 方法描述:进行聊天 * 日 期:2016年6月21日 下午9:08:57 */ @OnMessage public void message(Session session,String json){ //将json串转成java对象 Content content = gson.fromJson(json, Content.class); if(content.getType()==1){ //广播 Message message = new Message(); message.setUsernames(this.names); message.setContent(this.username,content.getMsg()); broadcast(this.sessions,message.toJson()); }else{ //单聊 //根据username找到对应的session对象 String chatToWho = content.getChatToWho(); Session to_session = map.get(chatToWho); Message message = new Message(); message.setUsernames(this.names); message.setContent(this.username,"<font color='red'>"+content.getMsg()+"</font>"); //向目标发送信息 try { to_session.getBasicRemote().sendText(message.toJson()); } catch (IOException e) { e.printStackTrace(); } } } /** * * 方法描述:退出聊天室 * 日 期:2016年6月21日 下午9:08:57 */ @OnClose public void close(Session session){ //session集合清除当前用户 sessions.remove(session); //用户列表集合清除当前用户 names.remove(username); //退出聊天室提示语 String msg = username+"退出聊天室!!<br/>"; //创建message对象 Message message = new Message(); message.setWelcome(msg); message.setUsernames(this.names); //广播 broadcast(this.sessions,message.toJson()); } /** * * 方法描述:广播 * 日 期:2016年6月21日 下午9:08:57 */ public void broadcast(List<Session> ss,String msg){ //遍历session集合 for (Session session : ss) { try { //服务端向客户端发送消息 session.getBasicRemote().sendText(msg); } catch (IOException e) { e.printStackTrace(); } } } }
相关文章推荐
- linux yum命令详解
- iOS App上传项目遇到的问题
- 【bzoj1568】[JSOI2008]Blue Mary开公司 超哥线段树
- lvm基本应用,扩展及缩减实现
- Android开发中结束所有Activity的方法
- 浅谈Python装饰器
- elf文件格式与动态链接库
- Android 程序启动另一个程序
- STL基础
- AndroidStudio创建带有toolbar的模板
- 【记录】SMT32 USART发送接收
- Redis Sentinel机制与用法(一)
- jsp核心标签库(JSTL)
- 傅里叶
- 文章标题
- MATLAB中的trace函数,求矩阵的迹
- 安卓手册 第二章(了解项目)
- onMeasure
- java基础一:发展史、特性、架构、代码执行原理、开发环境搭建
- 编程宗派的融合