WebSocket

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_第1张图片

创建webSocket启动文件

WebSocket_第2张图片

创建登录页面

WebSocket_第3张图片

创建登录Servlet

WebSocket_第4张图片

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);
}

创建聊天页面

WebSocket_第5张图片

<%@ 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实体类

WebSocket_第6张图片
WebSocket_第7张图片
WebSocket_第8张图片

创建Content实体类

WebSocket_第9张图片
WebSocket_第10张图片

创建WebSocket服务端

WebSocket_第11张图片

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();
            }
        }
    }
}

你可能感兴趣的:(WebSocket)