Sockjs node что это
Spring Websocket + SockJs. How it works?
Доброго времени суток уважаемые хабравчане. В данной статье хочу продолжить рассказ устройства Spring Websocket, рассмотрев серверную реализацию Spring Websocket + SockJs.
SockJs — это JavaScript библиотека, которая обеспечивает двусторонний междоменный канал связи между клиентом и сервером. Другими словами SockJs имитирует WebSocket API. Под капотом SockJS сначала пытается использовать нативную реализацию WebSocket API. Если это не удается, используются различные транспортные протоколы, специфичные для браузера, и представляет их через абстракции, подобные WebSocket. Про порт данной библиотеки в мир Spring Frameworks мы сегодня и поговорим.
Использование Websocket и SockJs доступно в Spring с версии 4.0.
На данный момент, в зависимости от браузера, SockJs может использовать следующие транспортные протоколы:
Browser | Websockets | Streaming | Polling |
---|---|---|---|
IE 6, 7 | no | no | jsonp-polling |
IE 8, 9 (cookies=no) | no | xdr-streaming * | xdr-polling * |
IE 8, 9 (cookies=yes) | no | iframe-htmlfile | iframe-xhr-polling |
IE 10 | rfc6455 | xhr-streaming | xhr-polling |
Chrome 6-13 | hixie-76 | xhr-streaming | xhr-polling |
Chrome 14+ | hybi-10 / rfc6455 | xhr-streaming | xhr-polling |
Firefox Пример использования частичной загрузкиEventSourceВ качестве реализации данного протокола на клиентской стороне используется объект EventSource. Данный объект предназначен для передачи текстовых сообщений используя Http. Главным преимуществом данного подхода является автоматическое переподключение и наличие идентификаторов сообщения для возобновления потока данных. IFrameИдея использования IFrame заключается в возможности последовательной обработки страницы по мере загрузки данных из сервера. Схема взаимодействия довольно проста — создается скрытых IFrame, идет запрос на сервер, который возвращает шапку документа и держит соединение. Каждый раз когда появляются новые данные сервер обрамляет их в тег script и отправляет в IFrame. IFrame получив новый блок script начнет его выполнение. HtmlFileДанный подход используется в IE и заключается в оборачивании IFrame в объект ActiveX. А основное преимущество использования — сокрытие действий в IFrame от пользователя. Структура SockJsИерархия транспортных обработчиковИерархия сессийСоздание конфигурационного классаРеализацию метода withSockJS() можно увидеть в классе AbstractWebSocketHandlerRegistration. Основная задача данного метода создать фабрику SockJsServiceRegistration, из которой создается главный класс обработки Http запросов SockJsService. После создания экземпляра SockJsService происходит связывание данного сервиса с WebSocketHandler и преобразование в HandlerMapping. Адаптером в данном случае выступает класс SockJsHttpRequestHandler. При создании экземпляра SockJsService в него передается планировщик задач (TaskScheduler), который в дальнейшем будет использоваться для отсылки Heartbeat сообщений. В качестве кодека преобразования сообщений по умолчанию используется Jackson2SockJsMessageCodec Для подключения SockJs на клиентской стороне необходимо добавить javascript библиотеку, и создать SockJS объект, при этом изменив протокол нашего endpoint с ws(wss) на http(https) Описание алгоритма взаимодействияРабота начинается с клиентского запроса /info, в ответ на который сервер возвращает объект вида который указывает на доступные url для обработки клиентских запросов. необходимы ли куки и есть ли возможность использовать webSocket. На основании этих данных клиентская библиотека выбирает транспортный протокол. Все клиентские запросы имеют вид Для поддержания совместимости с Websocket Api SockJs использует кастомный протокол обмена сообщениями: Пример fallbackРассмотрим пример когда у нас на сервере нет возможности обработать Websocket, сделать это довольно просто, установив переменную webSocketEnabled в false в классе SockJsServiceRegistration Клиент проверит возможность открытия сокета вызовом /info. Получив негативный ответ, будут использоваться два канала для обмена сообщениями: один для приема сообщений — как правило streaming протокол, и один для отправки сообщений на сервер (http запросы). Данные каналы коммуникации будут связываться одной sessionId передаваемой в URL. При отправке сообщения с клиента запрос попадает на DispatcherServlet, от куда перенаправляется на наш адаптер SockJsHttpRequestHandler. Данный класс преобразовывает запрос и перенаправляет его в SockJsService, который делегирует функцию принятия сообщения на пользовательскую сессию SockJsSession. А так как наша сессия связана к обработчиком WebSocketHandler мы получаем отправленное сообщение в нашем обработчике. Для отправки сообщения клиенту, мы по прежнему используем WebSocketSession. Дело в том что SockJsSession является расширением WebSocketSession. А конкретные реализации SockJsSession привязаны к транспортному протокому. Поэтому на серверной стороне при вызове session.sendMessage(new TextMessage(«some message»)); происходит преобразование сообщения к конкретному типу протокола и отправка форматированного сообщения к клиенту. Вот, собственно, и вся магия возможности fallback при использовании SockJs. sockjsDocumentationReadmeSockJS-nodeSockJS for enterpriseAvailable as part of the Tidelift Subscription. The maintainers of SockJS and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more. SockJS family⚠️️ ATTENTION This is pre-release documentation. The documentation for the latest stable release is at: https://github.com/sockjs/sockjs-node/tree/v0.3.19 ️⚠️ What is SockJS?SockJS is a JavaScript library (for browsers) that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, Javascript API which creates a low latency, full duplex, cross-domain communication channel between the browser and the web server, with WebSockets or without. This necessitates the use of a server, which this is one version of, for Node.js. SockJS-node serverSockJS-node is a Node.js server side counterpart of SockJS-client browser library. To install sockjs-node run: A simplified echo SockJS server could look more or less like: (Take look at examples directory for a complete version.) Subscribe to SockJS mailing list for discussions and support. SockJS-node APIThe API design is based on common Node APIs like the Streams API or the Http.Server API. Server classSockJS module is generating a Server class, similar to Node.js http.createServer module. Where options is a hash which can contain: Server instanceOnce you have create Server instance you can hook it to the http.Server instance. Server instance is an EventEmitter, and emits following event: Event: connection (connection) A new connection has been successfully opened. Connection instanceA Connection instance supports Node Stream API and has following methods and properties: A Connection instance emits the following events: Event: data (message) A message arrived on the connection. Message is a unicode string. Event: close () Connection was closed. This event is triggered exactly once for every connection. FootnoteA fully working echo server does need a bit more boilerplate (to handle requests unanswered by SockJS), see the echo example for a complete code. ExamplesIf you want to see samples of running code, take a look at: Connecting to SockJS-node without the clientAlthough the main point of SockJS it to enable browser-to-server connectivity, it is possible to connect to SockJS from an external application. Any SockJS server complying with 0.3 protocol does support a raw WebSocket url. The raw WebSocket url for the test server looks like: You can connect any WebSocket RFC 6455 compliant WebSocket client to this url. This can be a command line client, external application, third party code or even a browser (though I don’t know why you would want to do so). Note: This endpoint will not send any heartbeat packets. Deployment and load balancingThere are two issues that need to be considered when planning a non-trivial SockJS-node deployment: WebSocket-compatible load balancer and sticky sessions (aka session affinity). WebSocket compatible load balancerOften WebSockets don’t play nicely with proxies and load balancers. Deploying a SockJS server behind Nginx or Apache could be painful. Fortunately recent versions of an excellent load balancer HAProxy are able to proxy WebSocket connections. We propose to put HAProxy as a front line load balancer and use it to split SockJS traffic from normal HTTP data. Take a look at the sample SockJS HAProxy configuration. The config also shows how to use HAproxy balancing to split traffic between multiple Node.js servers. You can also do balancing using dns names. Sticky sessionsIf you plan deploying more than one SockJS server, you must make sure that all HTTP requests for a single session will hit the same server. SockJS has two mechanisms that can be useful to achieve that: Development and testingIf you want to work on SockJS-node source code, you need to clone the git repo and follow these steps. First you need to install dependencies: If compilation succeeds you may want to test if your changes pass all the tests. Currently, there are two separate test suites. SockJS-protocol Python testsTo run it run something like: SockJS-client Karma testsTo run it run something like: Various issues and design considerationsAuthorisationSockJS-node does not expose cookies to the application. This is done deliberately as using cookie-based authorisation with SockJS simply doesn’t make sense and will lead to security issues. Cookies are a contract between a browser and an http server, and are identified by a domain name. If a browser has a cookie set for particular domain, it will pass it as a part of all http requests to the host. But to get various transports working, SockJS uses a middleman Deploying SockJS on HerokuLong polling is known to cause problems on Heroku, but workaround for SockJS is available. Openbase helps developers choose among and use millions of open-source packages, so they can build amazing products faster. Sockjs node что этоSockJS for enterprise Available as part of the Tidelift Subscription. The maintainers of SockJS and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more. ⚠️ ️ ATTENTION This is pre-release documentation. The documentation for the latest stable release is at: https://github.com/sockjs/sockjs-node/tree/v0.3.19 ️ ⚠️ SockJS is a JavaScript library (for browsers) that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, Javascript API which creates a low latency, full duplex, cross-domain communication channel between the browser and the web server, with WebSockets or without. This necessitates the use of a server, which this is one version of, for Node.js. SockJS-node is a Node.js server side counterpart of SockJS-client browser library. To install sockjs-node run: A simplified echo SockJS server could look more or less like: (Take look at examples directory for a complete version.) Subscribe to SockJS mailing list for discussions and support. The API design is based on common Node APIs like the Streams API or the Http.Server API. SockJS module is generating a Server class, similar to Node.js http.createServer module. Where options is a hash which can contain: Once you have create Server instance you can hook it to the http.Server instance. Server instance is an EventEmitter, and emits following event: Event: connection (connection) A new connection has been successfully opened. A Connection instance supports Node Stream API and has following methods and properties: A Connection instance emits the following events: Event: data (message) A message arrived on the connection. Message is a unicode string. Event: close () Connection was closed. This event is triggered exactly once for every connection. A fully working echo server does need a bit more boilerplate (to handle requests unanswered by SockJS), see the echo example for a complete code. If you want to see samples of running code, take a look at: Connecting to SockJS-node without the client Although the main point of SockJS it to enable browser-to-server connectivity, it is possible to connect to SockJS from an external application. Any SockJS server complying with 0.3 protocol does support a raw WebSocket url. The raw WebSocket url for the test server looks like: You can connect any WebSocket RFC 6455 compliant WebSocket client to this url. This can be a command line client, external application, third party code or even a browser (though I don’t know why you would want to do so). Note: This endpoint will not send any heartbeat packets. Deployment and load balancing There are two issues that need to be considered when planning a non-trivial SockJS-node deployment: WebSocket-compatible load balancer and sticky sessions (aka session affinity). WebSocket compatible load balancer Often WebSockets don’t play nicely with proxies and load balancers. Deploying a SockJS server behind Nginx or Apache could be painful. Fortunately recent versions of an excellent load balancer HAProxy are able to proxy WebSocket connections. We propose to put HAProxy as a front line load balancer and use it to split SockJS traffic from normal HTTP data. Take a look at the sample SockJS HAProxy configuration. The config also shows how to use HAproxy balancing to split traffic between multiple Node.js servers. You can also do balancing using dns names. If you plan deploying more than one SockJS server, you must make sure that all HTTP requests for a single session will hit the same server. SockJS has two mechanisms that can be useful to achieve that: Development and testing If you want to work on SockJS-node source code, you need to clone the git repo and follow these steps. First you need to install dependencies: If compilation succeeds you may want to test if your changes pass all the tests. Currently, there are two separate test suites. SockJS-protocol Python tests To run it run something like: SockJS-client Karma tests To run it run something like: Various issues and design considerations SockJS-node does not expose cookies to the application. This is done deliberately as using cookie-based authorisation with SockJS simply doesn’t make sense and will lead to security issues. Cookies are a contract between a browser and an http server, and are identified by a domain name. If a browser has a cookie set for particular domain, it will pass it as a part of all http requests to the host. But to get various transports working, SockJS uses a middleman Deploying SockJS on Heroku Long polling is known to cause problems on Heroku, but workaround for SockJS is available. Sockjs node что этоSockJS for enterprise Available as part of the Tidelift Subscription. The maintainers of SockJS and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more. ⚠️ ️ ATTENTION This is pre-release documentation. The documentation for the latest stable release is at: https://github.com/sockjs/sockjs-node/tree/v0.3.19 ️ ⚠️ SockJS is a JavaScript library (for browsers) that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, Javascript API which creates a low latency, full duplex, cross-domain communication channel between the browser and the web server, with WebSockets or without. This necessitates the use of a server, which this is one version of, for Node.js. SockJS-node is a Node.js server side counterpart of SockJS-client browser library. To install sockjs-node run: A simplified echo SockJS server could look more or less like: (Take look at examples directory for a complete version.) Subscribe to SockJS mailing list for discussions and support. The API design is based on common Node APIs like the Streams API or the Http.Server API. SockJS module is generating a Server class, similar to Node.js http.createServer module. Where options is a hash which can contain: Once you have create Server instance you can hook it to the http.Server instance. Server instance is an EventEmitter, and emits following event: Event: connection (connection) A new connection has been successfully opened. A Connection instance supports Node Stream API and has following methods and properties: A Connection instance emits the following events: Event: data (message) A message arrived on the connection. Message is a unicode string. Event: close () Connection was closed. This event is triggered exactly once for every connection. A fully working echo server does need a bit more boilerplate (to handle requests unanswered by SockJS), see the echo example for a complete code. If you want to see samples of running code, take a look at: Connecting to SockJS-node without the client Although the main point of SockJS it to enable browser-to-server connectivity, it is possible to connect to SockJS from an external application. Any SockJS server complying with 0.3 protocol does support a raw WebSocket url. The raw WebSocket url for the test server looks like: You can connect any WebSocket RFC 6455 compliant WebSocket client to this url. This can be a command line client, external application, third party code or even a browser (though I don’t know why you would want to do so). Note: This endpoint will not send any heartbeat packets. Deployment and load balancing There are two issues that need to be considered when planning a non-trivial SockJS-node deployment: WebSocket-compatible load balancer and sticky sessions (aka session affinity). WebSocket compatible load balancer Often WebSockets don’t play nicely with proxies and load balancers. Deploying a SockJS server behind Nginx or Apache could be painful. Fortunately recent versions of an excellent load balancer HAProxy are able to proxy WebSocket connections. We propose to put HAProxy as a front line load balancer and use it to split SockJS traffic from normal HTTP data. Take a look at the sample SockJS HAProxy configuration. The config also shows how to use HAproxy balancing to split traffic between multiple Node.js servers. You can also do balancing using dns names. If you plan deploying more than one SockJS server, you must make sure that all HTTP requests for a single session will hit the same server. SockJS has two mechanisms that can be useful to achieve that: Development and testing If you want to work on SockJS-node source code, you need to clone the git repo and follow these steps. First you need to install dependencies: If compilation succeeds you may want to test if your changes pass all the tests. Currently, there are two separate test suites. SockJS-protocol Python tests To run it run something like: SockJS-client Karma tests To run it run something like: Various issues and design considerations SockJS-node does not expose cookies to the application. This is done deliberately as using cookie-based authorisation with SockJS simply doesn’t make sense and will lead to security issues. Cookies are a contract between a browser and an http server, and are identified by a domain name. If a browser has a cookie set for particular domain, it will pass it as a part of all http requests to the host. But to get various transports working, SockJS uses a middleman Deploying SockJS on Heroku Long polling is known to cause problems on Heroku, but workaround for SockJS is available. What is SockJS?SockJS is a JavaScript library (for browsers) that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, Javascript API which creates a low latency, full duplex, cross-domain communication channel between the browser and the web server, with WebSockets or without. This necessitates the use of a server, which this is one version of, for Node.js. SockJS-node serverSockJS-node is a Node.js server side counterpart of SockJS-client browser library written in CoffeeScript. To install sockjs-node run: A simplified echo SockJS server could look more or less like: (Take look at examples directory for a complete version.) Subscribe to SockJS mailing list for discussions and support. SockJS-node APIThe API design is based on common Node APIs like the Streams API or the Http.Server API. Server classSockJS module is generating a Server class, similar to Node.js http.createServer module. Where options is a hash which can contain: Server instanceOnce you have create Server instance you can hook it to the http.Server instance. Where options can overshadow options given when creating Server instance. Server instance is an EventEmitter, and emits following event: Event: connection (connection) A new connection has been successfully opened. Connection instanceA Connection instance supports Node Stream API and has following methods and properties: A Connection instance emits the following events: Event: data (message) A message arrived on the connection. Message is a unicode string. Event: close () Connection was closed. This event is triggered exactly once for every connection. FootnoteA fully working echo server does need a bit more boilerplate (to handle requests unanswered by SockJS), see the echo example for a complete code. ExamplesIf you want to see samples of running code, take a look at: Connecting to SockJS-node without the clientAlthough the main point of SockJS it to enable browser-to-server connectivity, it is possible to connect to SockJS from an external application. Any SockJS server complying with 0.3 protocol does support a raw WebSocket url. The raw WebSocket url for the test server looks like: You can connect any WebSocket RFC 6455 compliant WebSocket client to this url. This can be a command line client, external application, third party code or even a browser (though I don’t know why you would want to do so). Note: This endpoint will not send any heartbeat packets. Deployment and load balancingThere are two issues that need to be considered when planning a non-trivial SockJS-node deployment: WebSocket-compatible load balancer and sticky sessions (aka session affinity). WebSocket compatible load balancerOften WebSockets don’t play nicely with proxies and load balancers. Deploying a SockJS server behind Nginx or Apache could be painful. Fortunately recent versions of an excellent load balancer HAProxy are able to proxy WebSocket connections. We propose to put HAProxy as a front line load balancer and use it to split SockJS traffic from normal HTTP data. Take a look at the sample SockJS HAProxy configuration. The config also shows how to use HAproxy balancing to split traffic between multiple Node.js servers. You can also do balancing using dns names. Sticky sessionsIf you plan deploying more than one SockJS server, you must make sure that all HTTP requests for a single session will hit the same server. SockJS has two mechanisms that can be useful to achieve that: Development and testingIf you want to work on SockJS-node source code, you need to clone the git repo and follow these steps. First you need to install dependencies: You’re ready to compile CoffeeScript: If compilation succeeds you may want to test if your changes pass all the tests. Currently, there are two separate test suites. For both of them you need to start a SockJS-node test server (by default listening on port 8081): SockJS-protocol Python testsTo run it run something like: SockJS-client QUnit testsYou need to start a second web server (by default listening on 8080) that is serving various static html and javascript files: At that point you should have two web servers running: sockjs-node on 8081 and sockjs-client on 8080. When you open the browser on http://localhost:8080/ you should be able run the QUnit tests against your sockjs-node server. Various issues and design considerationsAuthorisationSockJS-node does not expose cookies to the application. This is done deliberately as using cookie-based authorisation with SockJS simply doesn’t make sense and will lead to security issues. Cookies are a contract between a browser and an http server, and are identified by a domain name. If a browser has a cookie set for particular domain, it will pass it as a part of all http requests to the host. But to get various transports working, SockJS uses a middleman Deploying SockJS on HerokuLong polling is known to cause problems on Heroku, but workaround for SockJS is available.
|