`
rensanning
  • 浏览: 3553346 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
Efef1dba-f7dd-3931-8a61-8e1c76c3e39f
使用Titanium Mo...
浏览量:38235
Bbab2146-6e1d-3c50-acd6-c8bae29e307d
Cordova 3.x入门...
浏览量:607654
C08766e7-8a33-3f9b-9155-654af05c3484
常用Java开源Libra...
浏览量:682844
77063fb3-0ee7-3bfa-9c72-2a0234ebf83e
搭建 CentOS 6 服...
浏览量:89568
E40e5e76-1f3b-398e-b6a6-dc9cfbb38156
Spring Boot 入...
浏览量:402165
Abe39461-b089-344f-99fa-cdfbddea0e18
基于Spring Secu...
浏览量:69772
66a41a70-fdf0-3dc9-aa31-19b7e8b24672
MQTT入门
浏览量:91866
社区版块
存档分类
最新评论

基础知识 - WebSocket

 
阅读更多
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>&nbsp;</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 楼 FengZiIT 2017-01-23  
GoEasy推送,它有Restful API 支持多语言,同时它也支持客户端推送。由于它支持websocket 和polling两种连接方式所以兼顾大多数主流浏览器,低版本的IE浏览器也是支持的,个人觉得很不错。网址:goeasy.io

相关推荐

    前端开源库-home-assistant-js-websocket

    ### WebSocket基础知识 WebSocket是一种在客户端和服务器之间建立长连接的协议,相比于传统的HTTP协议,它提供双向通信能力,即服务器和客户端可以同时发送数据,大大提高了实时性。WebSocket API被设计成与...

    netty-websocket-proxy-1.3.1-bin.zip

    了解这些基础知识后,你可以深入学习 Netty 的文档,探索更多高级特性,例如自定义的 ChannelHandler,以及如何利用 Netty 的灵活性来适应不断变化的业务需求。此外,还可以研究 WebSocket 协议规范,以便更好地理解...

    Java-WebSocket

    1. **WebSocket基础知识**:WebSocket协议是HTTP的升级版,它通过一个Upgrade头字段将HTTP连接转换为WebSocket连接。WebSocket连接一旦建立,就可以在同一个TCP连接上进行多次双向数据交换,无需为每个消息创建新的...

    node-websocket-server-master

    总的来说,"node-websocket-server-master" 提供了一个学习和实践使用 Node.js 构建 WebSocket 服务器的机会,涵盖了从基础的 Node.js 编程到高级的网络应用开发等多个方面。通过研究这个项目,开发者不仅可以提升对...

    springMvc-websocket-demo

    标题"springMvc-websocket-demo"指示这是一个使用Spring MVC框架和WebSocket技术的示例项目。这个项目的目的是演示如何在Spring MVC应用中集成WebSocket,以便实现实时通信功能。 描述中的关键词"集成websocket的...

    PyPI 官网下载 | django-websocket-0.3.0.tar.gz

    标题"PyPI 官网下载 | django-websocket-0.3.0.tar.gz"表明这是一个从Python Package Index (PyPI) 官方网站获取的软件包,名为`django-websocket-0.3.0`,其打包格式为tar.gz。这个包是针对Python开发的,特别是...

    springboot-websocket例子

    以下是对"springboot-websocket例子"中可能包含的知识点的详细解释: 1. **Spring Boot基础**: Spring Boot简化了Spring应用程序的创建,通过自动配置和起步依赖(Starter POMs)使得开发过程更加便捷。在这个...

    WebSocketPush-master.zip

    2. **Kotlin基础**:项目使用Kotlin作为编程语言,因此会涉及到Kotlin的基本语法、函数、类和扩展等特性。 3. **Android WebSocket客户端**:学习如何在Android应用中创建WebSocket客户端,包括初始化连接、监听...

    ios-webSocket测试.zip

    在"webSocketDemo"这个项目中,我们可以看到以下关键知识点: 1. **初始化WebSocket**:在iOS应用中,首先需要实例化一个SRWebSocket对象,设置其URL(WebSocket服务器地址)和协议类型(ws或wss,分别对应不加密和...

    FreakDev-PhoneGap-Android-HTML5-WebSocket

    6. **Android开发基础知识**:虽然主要使用HTML5开发,但理解Android的基本概念和生命周期对于调试和适配是必要的。 7. **版本控制**:使用Git进行版本管理和协作,理解和使用Git命令如`clone`、`commit`、`push`和`...

    as3-websocket-server-master.rar

    `as3-websocket-server-master`是一个使用AS3实现的WebSocket服务器项目,由国外大神创建。 该项目的核心知识点包括: 1. WebSocket API:AS3中的WebSocket API提供了创建和管理WebSocket连接的接口。`WebSocket`...

    基于java的开发源码-WebSocket协议的实现 WebSocket4J.zip

    WebSocket协议是一种在客户端和服务器之间建立长久连接的通信协议,它允许双向通信,即服务器可以主动向客户端推送数据,而不仅仅是...同时,源码也是进一步定制和扩展WebSocket功能的基础,可以满足特定场景的需求。

    Laravel开发-websocket

    首先,让我们了解Laravel的基础知识。Laravel是由Taylor Otwell创建的一个开源PHP框架,以其优雅的语法、丰富的特性以及对开发者友好的设计而闻名。它提供了路由、中间件、数据库迁移、队列处理、任务调度等一系列...

    springboot-websocket.rar

    1. Spring Boot基础:包括Spring Boot的起步依赖、自动配置、MVC、Actuator等特性。 2. WebSocket集成:如何在Spring Boot应用中配置WebSocket,使用`@ServerEndpoint`注解创建WebSocket端点,处理连接、发送和接收...

    stomp-websocket_jswebsocketstomp_源码

    1. **WebSocket基础** WebSocket API是HTML5引入的一个新特性,它提供了全双工的通信通道,不同于HTTP的请求-响应模式。WebSocket连接一旦建立,就可以在服务器和客户端之间持续传输数据,而无需反复建立新的连接。...

    Spring+Netty+WebSocket实例

    总结来说,Spring、Netty和WebSocket的结合为构建实时、双向通信的应用提供了强大的基础。通过深入理解这三个组件的工作原理和它们之间的交互,开发者能够创建出满足各种需求的现代Web应用。本实例的实践价值在于它...

    08-websocket.md

    前端工程师面试中考察WebSocket协议的知识点主要是为了评估求职者是否具备全栈开发的能力和了解前后端通信的基本原理。...这些知识点不仅仅是面试时的谈资,也是日常开发工作中不可或缺的基础知识。

    基于Java的实例源码-WebSocket通讯框架 jWebSocket.zip

    通过对源码的阅读和调试,我们可以学习到更多关于WebSocket协议和Java网络编程的知识。 这个实例源码提供了完整的jWebSocket使用示例,包括服务器端和客户端的实现,非常适合初学者和开发者参考学习。通过实践,你...

    Arduino-Websocket-项目开发

    **一、Arduino基础知识** Arduino是一款开源电子原型平台,适合初学者和专业人士使用。它包括硬件(各种不同类型的Arduino板)和软件(Arduino IDE),用户可以通过编写简单的代码来控制硬件设备。 **二、Websocket...

Global site tag (gtag.js) - Google Analytics