WebSocket是一种新的协议,本质上和HTTP一样(握手连接等)。但它并不是在HTTP之上模拟推送,而是直接在TCP之上定义了帧Frame,实现客户端与服务器间的全双工通讯。
https://en.wikipedia.org/wiki/WebSocket
关于浏览器与服务器间的实时通讯,比较常见的方案是Polling轮询(Ajax)、Long Polling轮询(Comet)。也可以自己写Socket长连接,自定义协议,自己实现封包,拆包以及解决tcp粘包等问题。这些方案都比较麻烦。
Polling
|
Comet
/ \
/ \
SSE WebSocket
Polling、SSE、WebSocket的通讯流程:
WebSocket当初是作为HTML5的一部分,后来经过多次修订后独立出来 成为IETF的RFC 6455。目前大部分浏览器都支持WebSocket。 http://caniuse.com/#feat=websockets
(1)WebSocket组成:
WebSocket Protocol: IETF https://tools.ietf.org/html/rfc6455
WebSocket API: W3C https://www.w3.org/TR/2011/WD-websockets-20110929/
(2)WebSocket的subprotocol:
STOMP (Simple/Streaming Text Oriented Messaging Protocol) http://stomp.github.io/
WAMP (Web Application Messaging Protocol) http://wamp-proto.org/
XMPP (Extensible Messaging and Presence Protocol) https://xmpp.org/
AMQP (Advanced Message Queuing Protocol) https://www.amqp.org/
MQTT (Message Queue Telemetry Transport) http://mqtt.org/
(3)WebSocket特点:
从HTTP到WebScoket协议通过“Upgrade”建立连接
运行端口80/443,所以Proxy和Firewall是友好的 ws:// wss://
HTTP兼容的握手,基于Cookie的认证
并非纯正的TCP Socket,可以传输:UTF-8字符、二进制Frame
大大减少网络流量
(4)服务器端实现:
Java: JavaEE7实现了WebSocket协议(JSR 356)、Jetty
node.js: https://github.com/websockets/ws
https://github.com/socketio/socket.io
PHP: https://github.com/ratchetphp/Ratchet/
Ruby: https://github.com/igrigorik/em-websocket
等
uWebSockets https://github.com/uWebSockets/uWebSockets
Undertow http://undertow.io/index.html
(5)WebSocket API:
①JavaScript API
// Create a socket instance
var socket = new WebSocket('ws://localhost:8080');
// Open the socket
socket.onopen = function(event) {
// Send an initial message
socket.send('I am the client and I\'m listening!');
// Listen for messages
socket.onmessage = function(event) {
console.log('Client received a message',event);
};
// Listen for socket closes
socket.onclose = function(event) {
console.log('Client notified socket has closed',event);
};
// To close the socket....
//socket.close()
};
客户端兼容性测试:
if( window.WebSocket ){
// supported
}else{
// not supported
}
②Events:
ws.onopen = function(e) { };
ws.onmessage = function(e) { };
ws.onerror = function(e) { };
ws.onclose = function(e) { };
ws.addEventListener('message', onMessageHandler);
ws.addEventListener('open', onOpenHandler);
ws.addEventListener('close', onCloseHandler);
***on<eventname> 或 addEventListener() 都可以。
③Methods:
ws.send(data);
// Sending String
ws.send('your message');
// Sending canvas ImageData as ArrayBuffer
var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
binary[i] = img.data[i];
}
ws.send(binary.buffer);
// Sending file as Blob (ws.binaryType = 'arraybuffer';)
var file = document.querySelector('input[type="file"]').files[0];
ws.send(file);
ws.close();
ws.close(1000, "Goodbye, World!"); // pass a code and a reason
④Attributes:
ws.readyState
ws.bufferedAmount
ws.protocol
(6)node.js的简单测试
server.js
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({port: 8181});
wss.on('connection', function(ws) {
console.log('client connected');
ws.on('message', function(message) {
console.log(message);
});
});
client.html
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Echo Demo</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
var ws = new WebSocket("ws://localhost:8181"); // wss:// (if using TLS)
ws.onopen = function(e) {
console.log('Connection to server opened');
};
ws.onerror = function (error) {
console.log('WebSocket Error ' + error);
};
ws.onmessage = function (e) {
console.log('Server: ' + e.data);
};
function sendMessage() {
ws.send($('#message').val());
}
</script>
</head>
<body>
<div class="vertical-center">
<div class="container">
<p> </p>
<form role="form" id="chat_form" onsubmit="sendMessage(); return false;">
<div class="form-group">
<input class="form-control" type="text" name="message" id="message" placeholder="Type text to echo in here" value="" autofocus/>
</div>
<button type="button" id="send" class="btn btn-primary" onclick="sendMessage();">Send!</button>
</form>
</div>
</div>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</body>
</html>
HTTP Headers
Handshake Request
Handshake Response
101 Switching Protocols
upgraded HTTP request
(7)Java测试 - Jetty WebSocket Example
@WebServlet(urlPatterns="/test")
public class WebSocketServletImpl extends WebSocketServlet {
@Override
public void configure(WebSocketServletFactory factory) {
factory.register(WebSocketSample.class);
}
}
@WebSocket
public class WebSocketSample {
@OnWebSocketConnect
public void onConnect(Session session) {
System.out.println(session.getRemoteAddress().getHostString() + " connected!");
}
@OnWebSocketMessage
public void onText(String message) {
System.out.println("Message received:" + message);
if (session.isOpen()) {
session.getRemote().sendString(message + " is received.");
}
}
@OnWebSocketClose
public void onClose(int statusCode, String reason) {
WSystem.out.println(session.getRemoteAddress().getHostString() + " closed!");
}
}
(8)Java测试 - JavaEE7 WebSocket Example
@ServerEndpoint("/ws/sample")
public class SampleEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("New connection with client: {0}" + session.getId());
}
@OnMessage
public String onMessage(String message, Session session) {
System.out.println("New message from Client [{0}]: {1}" + new Object[] {session.getId(), message});
return "Server received [" + message + "]";
}
@OnClose
public void onClose(Session session) {
System.out.println("Close connection for client: {0}" + session.getId());
}
@OnError
public void onError(Throwable exception, Session session) {
System.out.println("Error for client: {0}" + session.getId());
}
}
Java WebSocket API : JSR 356
(9)Java测试 - Spring WebSocket Example
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat").withSockJS();
}
}
@MessageMapping("/chat")
@SendTo("/topic/messages")
public OutputMessage send(Message message) throws Exception {
String time = new SimpleDateFormat("HH:mm").format(new Date());
return new OutputMessage(message.getFrom(), message.getText(), time);
}
(10)Java测试 - Spring Boot WebSocket Example
pom.xml
<!-- use websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
@Component
public class EchoHandler extends TextWebSocketHandler {
private Map<String, WebSocketSession> sessionPool = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
this.sessionPool.put(session.getId(), session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
this.sessionPool.remove(session.getId());
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
for (Entry<String, WebSocketSession> entry : this.sessionPool.entrySet()) {
entry.getValue().sendMessage(message);
}
}
}
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private EchoHandler echoHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(echoHandler, "/echo");
}
}
(11)第三方API
Sockjs https://github.com/sockjs
STOMP.js https://github.com/jmesnil/stomp-websocket
服务器端:
@Configuration
@EnableWebSocketMessageBroker
public class AppWebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/calcApp");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/add").withSockJS();
}
}
@Controller
public class WebSocketController {
@MessageMapping("/add" )
@SendTo("/topic/showResult")
public Result addNum(CalcInput input) throws Exception {
Thread.sleep(2000);
Result result = new Result(input.getNum1()+"+"+input.getNum2()+"="+(input.getNum1()+input.getNum2()));
return result;
}
}
客户端:
var socket = new SockJS('/Spring4WebSocket/add');
var stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/showResult', function(calResult){
console.log(calResult.body);
});
});
(12)问题
LoadBalancer
Web Filtering
参考:
https://hpbn.co/websocket/
http://www.ibm.com/developerworks/cn/java/j-lo-WebSocket/
https://www.webcodegeeks.com/html5/html5-websocket-example/
http://qiita.com/yuba/items/00fc1892b296fb7b8de9
http://www.slideshare.net/ffdead/the-html5-websocket-api
- 大小: 18.4 KB
- 大小: 92.4 KB
- 大小: 29.9 KB
- 大小: 14.2 KB
- 大小: 22.9 KB
- 大小: 9.3 KB
- 大小: 26.4 KB
分享到:
相关推荐
1 byte(字节) = 8 bit(位)这种基础知识就不说了 Fin :1 bit 标识着这个 Frame 是不是一个消息中的最后一条 有的消息可能被拆成了若干个Frame RSV1, RSV2, RSV3 : 每个都是 1 bit 就是 Reserved(保留)的意思...
Spotify WebSocket API 入门 注意:此 API 仅适用于付费 Spotify 帐户。 我对这个限制完全没问题,不会... 使用 API 非常简单,以下是基础知识: sp = Spotify("username", "password") results = sp.search("carly ra
websocket协议使用场景,优点和基础知识介绍 websocket一次握手,TCP三次握手以及数据帧传输 websocket对象,属性,方法,事件 websocket在前后端的实战应用级代码示例
通过呆着读者手写速成版本的websocket入门案例,以项目案例的方式带你体验websocket的使用场景和相关知识内容。 适合人群:具备一定的开发能力和编程基础,工作1-3年的研发人员 能学到什么: 1.SpringBoot项目的框架...
java springboot,websocket相关基础知识,html+css+js! 内容概要: 里面包括登录界面,聊天界面!包括好友上线,离线提醒! 项目进展: 完善程度百分之八十,里面并没有包含群聊,多聊!只是一对一聊! 现在存在的...
这个 repo 可以存在,因为它是学习一些 C++ 的时候,所以如果你正在寻找一些生产质量的东西并且偶然来到这里,那么干脆走开:) 虽然向我推荐了一些教程(或书籍) - 这对我很有用你在学习基础知识时 - 会非常感激。...
其他内容(从基础知识到URL处理再到多线程) -网络框架 -WebSocket服务器库 -WebSocket客户端库 所有这些库都可以用作共享库,静态库或仅标头库。 ( 需要构建随附的一些第三方库,例如和uSockets; 需要 。) ...
该项目是通过引导的。 您将在下面找到一些有关如何执行常见任务的信息。 您可以在找到本指南的最新版本。 目录 自动格式化代码 ...配置WebSocket代理 在开发中使用HTTPS 在服务器上生成动态<met
websocket介绍、使用场景分享、学习课程需要什么基础 笔记: websocket介绍: WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给...
02.Netty 介绍与相关基础知识 03.基于web.socket简单聊天DEM实现-Netty服务器类 04.基于web.socket简单聊天DEMO实现-ChannelHandler实现 05.websocket以及前端代码编写 06.websocket以及前端代码编写测试 07.MUI、...
基础知识的仓库 git (帮忙start一下!!!) 文档 基础: 这条知识链层层相扣,缺一不可 操作系统->计算机网络->java jvm虚拟机-> java 多线程,高并发 ->设计模式 -> spring源码 请学习多线程前,先学操作系统和jvm ...
Tuts+ 课程:WebSocket Powered Rails 应用... 如果您了解 Ruby on Rails 的基础知识,并且准备好了解使用 WebSockets 的强大功能,那么这就是为您准备的课程! Tuts+ 课程的源文件: Tuts+ 上可用,2015 年 1 月
- Spring Boot 基础知识,包括SpringBoot起步、配置详解、aop、filter、拦截器、监听、启动器、全局异常处理、外部Tomcat启动、HTTPS、监控 等。 - springboot-data - Spring Boot 数据库操作,包括SpringJDBC、...
但是随着项目的进展,我们的需求不断增长,我们的后端应用程序越来越像一个独立的库,因此我们选择使其成为一个独立的工具,以使社区受益并在更好的基础上取得进步。 :brain: 哲学 我们希望创建一个工具,使我们...
采用Java技术 WebSocket+mysql,利用spring mvc框架+...总的来说,毕业设计是高等教育中的一项重要环节,通过此过程,学生不仅能够巩固所学知识,还能培养独立思考和解决问题的能力,为将来的职业发展奠定坚实的基础。
基础教程与练习项目:从基础知识讲起,结合实际练习项目,让您轻松上手SSM开发。 进阶技术与案例分析:针对进阶开发者,提供深入的技术探讨和案例分析,助您深入理解SSM的高级特性。 实战项目与经验分享:通过实际...
有一定python基础知识,没有的话先去学一下,起码得会搭python环境 思路 利用selenium打开退会页面 第一关:手机验证码 安卓端(以下两种任选一个用就行): 利用macrodroid软件 监听,一旦监听到就立即通过HTTP请求...
这是的入门模板。
关于网络编程基础知识学习教学文件,章节有网络编程概述、网络相关术语、网络分层体系结构、即时通信的三种模式、C# Socket通信过程、WebSocket 编程。内容知识点设计网络编程基础、OSI/RM、TCP/IP模型、Socket网络...