websocket协议是基于Tcp的一种新的网络协议,它实现了客户端与服务器的双向通行,并允许服务端主动发送信息给客户端。WebSocket是html5中的协议。

Http协议与WebSocket协议:

Http协议只有1.0 和1.1 两个版本,

http协议是无状态的每一请求对应一个响应,而且响应完了就回结束连接,多个请求对应多个响应,每次都要重新建立连接。

在http1.1 中增加了 keep-alive (只是客户端的一种建议) ,用于在一个Http连接中,可以发送多个Request,接收多个Response。但依旧是每隔request对应一个response。

Connection:keep-alive

这个是通知服务器在 request/response 之后,不要理解断开tcp连接,后面的request/response 任然可以通过这个连接完成。但是这个只是个建议,服务端可能不支持,也可能时间长了,断开了连接。(通俗点就根服务端说下 ,后面可能还有事需要找你先不要挂了)

这个是不可能实现服务器主动push消息给客户端的。

那么如何能够实现呢?

But 我们可以使用ajax轮询 和long poll 技术,制造一个服务端push给客户端的假象。

那什么是Ajax轮询?

Ajax 轮询 就是隔几秒让浏览器发送请求询问服务端时候有消息了?

场景:

客户端:hi,有没有新信息(Request)
服务端:没有(Response)
客户端:hi,有没有新信息(Request)
服务端:没有。。(Response)
客户端:hi,有没有新信息(Request)
服务端:没有啊。。(Response)
客户端:hi有没有新消息(Request)
服务端:好了,有啦给你。(Response)
客户端:hi,有没有新消息(Request)
服务端:没有......

But 实际中这样会增加服务端的负载,降低服务端的效率。

什么是long poll 呢?

long poll 和ajax 轮询差不多,不过long poll 是阻塞的模式。也就是客户端发送一个request后 一直等待,知道服务端有消息response后才ok

场景:

客户端:hi,有没有新信息(Request)
服务端:没有(Response)
客户端:hi,有没有新信息(Request)
客户端:hi,有没有新信息(Request)

long pull 虽然降低了服务器的负载,但是需要服务器有很高的并发能力才可以。

ajax轮询、long poll技术虽然都能实现服务端消息的实时通知,但是各有缺点,都不是根本的解决办法。

既然他们都不行,那应该搞个新的协议。

WebSocket协议解决的客户端与服务端的双工通信的问题。

场景:

客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:13(HTTP Request)
服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)
客户端:麻烦你有信息的时候推送给我噢。。
服务端:ok,有的时候会告诉你的。
服务端:发斯蒂芬
服务端:啊实打实大师
服务端:哈哈哈哈哈啊哈
服务端:笑死我了哈哈哈

  

request header

Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: no-cache
Connection: Upgrade #通知服务器协议升级
Cookie: JSESSIONID=450BA8D626F785A1AE3BEB9AC9226CD0
Host: localhost:8099
Origin: http://localhost:8099
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: yjbBHsadoLeWtVNa+3Y2ow== #传输给服务器的key
Sec-WebSocket-Version: 13 #wesocket版本协议号13
Upgrade: websocket #协议升级为websocket协议
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Sec-WebSocket-Key 这个是客户端发送给服务端,服务端处理后再返回给客户端客户端进行验证 判断是否建立连接。
Connection: Upgrade #通知服务器协议升级
Upgrade: websocket #协议升级为websocket协议
这个就是Websocket的核心了,告诉Apache、Nginx等服务器:注意啦,发起的是Websocket协议,快点帮我找到对应的助理处理~不是HTTP。
Status Code:101 Switching Protocols  101 连接成功

 response Header:

Connection: upgrade #升级成功
Date: Thu, 12 Apr 2018 03:11:37 GMT
Sec-WebSocket-Accept: NbF/mYm1P/lNy0NsMWxYD1Wi1EE= #服务端处理之后的key
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
Server: Apache-Coyote/1.1
Upgrade: websocket

握手成功!

简单的代码示例:

jsp 客户端:

<%@ page language="java" import="java.util.*" 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>
<script type="text/javascript">
var webSocket = null;
if ('WebSocket' in window) {
webSocket = new WebSocket("ws://localhost:8099/webSocketTest");
} else {
alert("浏览器不支持webSocket");
} webSocket.onopen = function() {
writeDiv("websocket连接ok");
} webSocket.onmessage = function(event) {
writeDiv("client 接受的消息是:" + event.data);
} webSocket.onerror = function() {
writeDiv("发生错误");
} function sendMsg() {
var val = document.getElementById("inputText").value;
webSocket.send(" 客户端:" + val);
} function closes() {
webSocket.close();
} webSocket.onclose = function() {
webSocket.close();
writeDiv("WebSocket連接關閉");
} function writeDiv(innerHTML) {
var html = document.getElementById('message').innerHTML;
document.getElementById('message').innerHTML += innerHTML + '<br>';
}
</script>
<body> <input type="text" id="inputText">
<button id="but" onclick="sendMsg()">submit</button>
<br>
<button id="close" onclick="closes()">关闭webSocket连接</button>
<br>
<div id="message"></div>
</body>
</html>

服务端:

package com.tgb.SpringActivemq.controller;

import java.io.IOException;
import java.util.HashSet;
import java.util.Random;
import java.util.Set; import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint; import org.apache.log4j.Logger; @ServerEndpoint("/webSocketTest")
public class webSocketController { private int count = 0; static Set<Session> set = new HashSet<Session>(); static final Logger logger = Logger.getLogger(webSocketController.class); private Session session; @OnOpen
public void onOpen(Session sessio) {
this.session = sessio;
set.add(session);
this.count++;
logger.info("当前连接:" + this.count);
} // 接受消息 处理
@OnMessage
public void onMessage(String message, Session ss) {
logger.info("接受到的客户端消息是:" + message);
Random r = new Random();
int tet = r.nextInt(1000);
try {
ss.getBasicRemote().sendText("服务端发送的是:" + tet);
} catch (IOException e) {
e.printStackTrace();
}
} @OnError
public void Onerror(Session s, Throwable th) {
logger.info(th.getMessage());
} @OnClose
public void onClose(Session s) {
try {
s.close();
set.remove(s);
this.count--;
logger.info("当前连接数:" + this.count);
logger.info("CLOSE WEBSOCKET");
} catch (IOException e) {
e.printStackTrace();
}
}
}

  

 

webSocket的 原理 及 实现的更多相关文章

  1. WebSocket的原理,以及和Http的关系

    一.WebSocket是HTML5中的协议,支持持久连接:而Http协议不支持持久连接. 首先HTMl5指的是一系列新的API,或者说新规范,新技术.WebSocket是HTML5中新协议.新API. ...

  2. WebSocket的原理,以及和Http的关系 (转载)

    一.WebSocket是HTML5中的协议,支持持久连接:而Http协议不支持持久连接. 首先HTMl5指的是一系列新的API,或者说新规范,新技术.WebSocket是HTML5中新协议.新API. ...

  3. WebSocket协议-原理篇

    本篇文章主要讲述以下几点: WebSocket的原理与机制 WebSocket与Socket.io WebSocket兼容性 WebSocket的原理与机制 WebSocket协议分为两部分:握手和数 ...

  4. nginx支持websocket及websocket部分原理介绍

    nginx支持websocket及websocket部分原理介绍最近ipc通过websocket与server进行通行,经过无法通过nginx进行反向代理,只有直连nodejs端口.而且部署到阿里云用 ...

  5. Websocket(一)——原理及基本属性和方法

    初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处? 答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起. 举例 ...

  6. WebSocket的原理与优缺点

    websocket 是长连接,受网络限制比较大,需要处理好重连,比如用户进电梯或电信用户打个电话网断了,这时候就需要重连,如果 ws 一直重连不上,有些较复杂的业务方会不愿意的,是不是还要搞个 htt ...

  7. (转)WebSocket的原理

    前言:无聊逛知乎,就逛到H5的栏目去了,正好看到了关于Websocket的东西.个人是比较喜欢看这类风格的,转到博客分享,以便自己以后理解. ---------------------分割线----- ...

  8. 分析HTML5中WebSocket的原理

    目录结构   一.什么是Websocket websocket是html5提出的一个协议规范,参考rfc6455. 不过目前还都是在草案,没有成为标准,毕竟html5还在路上. websocket约定 ...

  9. 一文带你看懂WebSocket 的原理?为什么可以实现持久连接?

    工作之余在知乎上偶然看到一篇回帖,瞬间觉得之前看的那么多资料都不及这一篇让我对 websocket 的认知深刻易懂,之前看总完总觉得一知半解云里雾里.所以与大家共同分享一下一起学习.比较喜欢这种博客理 ...

  10. 【计算机网络】WebSocket实现原理分析

    1.介绍一下websocket和通信过程? 1.1 基本概念 [!NOTE] Websocket是应用层第七层上的一个应用层协议,它必须依赖 HTTP 协议进行一次握手 ,握手成功后,数据就直接从 T ...

随机推荐

  1. setTimeout异步

    同步任务和异步任务 同步和异步操作的区别就是是否阻碍后续代码的执行. 同步任务是那些没有被引擎挂起.在主线程上排队执行的任务.只有前一个任务执行完毕,才能执行后一个任务. 异步任务是那些被引擎放在一边 ...

  2. leecode第二百三十五题(二叉搜索树的最近公共祖先)

    /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...

  3. java枚举通俗实例解析

    1         枚举 1.1            枚举的作用 我们经常要定义一些常量值,例如日期(MONDAY,TUESDAY……)或者错误码等.可以将常量组织起来,统一进行管理.常量比较只是值 ...

  4. @RequestMapping的Ant风格URL

    Ant风格资源地址支持3中匹配符 ? 匹配文件名中一个字符. *   匹配 文件名中任意字符 **  匹配多层路径 例如 /hello/*/myspring 匹配 /hello/abc/mysprin ...

  5. LINQ to Entities 不识别方法“System.DateTime AddDays(Double)

    今天本想在linq里按照时间筛选一下超时的数据,一共两个字段FeedBackTime(计划反馈时间).EndTime(实际反馈时间).需求是这样的,查找数据库里所有EndTime大于FeedBackT ...

  6. (详细)华为V9 DUK-AL20的usb调试模式在哪里打开的方法

    当我们使用PC通过数据线链接到安卓手机的时候,如果手机没有开启USB开发者调试模式,PC则没办法成功识别我们的手机,有时我们使用的一些功能较好的软件好比以前我们使用的一个软件引号精灵,老版本就需要打开 ...

  7. android -------- Hawk数据库

    Hawk 是一个非常便捷的数据库  . 操作数据库只需一行代码 , 能存任何数据类型 . github 地址: https://github.com/orhanobut/hawk 一.概念 Share ...

  8. 解决ajax跨域

    今天要联调项目,前后端请求使用ajax,联调存在跨域问题,解决办法如下: (1)在本地的电脑上新建一个文件夹,用于前后端联调存放浏览器 缓存的 (2)打开桌面的谷歌浏览器图标(右键>属性> ...

  9. php(一)搭建php开发环境

    1.下载php语言包 php作为一门语言,本身可以是一个纯绿色版的"文件夹"——称之为"php语言包".windows版的下载地址:https://window ...

  10. Xshell利用lrzsz工具上传下载

    直接安装这个lrzsz工具 yum install lrzsz 上传 rz 下载 sz