前言如果建立实时性非常高的应用,我们可以使用WebSocket,Spring Framework 实现了WebSocket 应用级封装,本文是对Spring Framework WebSocket部分的翻译,如果对WebSocket不太了解可以看看我在16年与老师合著出版的书《Web异步与实时交互 iframe AJAX WebSocket开发实战》中我负责的WebSocket部分。. 消息架构 Today REST is a widely accepted, understood, and supported architecture for building web applications. It is an architecture that relies on having many URLs (nouns), a handful of HTTP methods (verbs), and other principles such as using hypermedia (links), remaining stateless, etc.REST的架构是通过很多URL去实现的.
Opened and commentedWhen we attempted to migrate our codebase from 4.3.3 to 5.0.2, our controller integration tests all failed, because our ApplicationContext in the test environment couldn't be created, since we have one controller that uses STOMP over a web socket. We actually aren't even testing STOMP messages in our integration tests. We only test simple HTTP requests, but again, those tests won't run because the ApplicationContext can't be created. This looks like a regression from 4.3.3.I reproduced the issue easily using an entirely different codebase, a sample application written to showcase testing of spring-websocket. See the example test at the Reference URL above (note the fork).Problems:.
WebSocketServerFactory.doStart throws an IllegalStateException because it doesn't have a DecoratedObjectFactory. This can be worked around pretty easily by setting the DecoratedObjectFactory.ATTR attribute on the ServletContext. WebSocketServerFactory throws a NullPointerException because it doesn't have an Executor and can't get one via a ContextHandler. This is because Spring's MockServletContext doesn't implement Jetty's ContextHandler.Context. I can’t seem to find a workaround because these spring-websocket types seem to form a chain of construction via new:.
WebMvcStompWebSocketEndpointRegistration. DefaultSockJsService. DefaultHandshakeHandler.
JettyRequestUpgradeStrategy. WebSocketServerFactoryFor the time being, we are working around the issue by omitting the web socket mappings from our integration test environment (no longer using @EnableWebSocketMessageBroker in our integration tests).
Until this issue is fixed, it seems we no longer have the option of adding tests that exercise the web socket.Affects: 5.0.2Reference URL. CommentedNot only that, but integration testing shouldn’t require copying stuff already in WebSocketConfig with slight modifications. One of the main points of integration testing is to make sure that everything is configured correctly. Substituting a fake a certain spot in the dependency graph should be simple, atomic operation (e.g. A single, trivial bean declaration). It shouldn’t require building and grafting in a sizable new dependency chain or branch. Ideally it’d be handled automatically by the test framework.I’d be open to suggesting API changes to improve testability if that would be helpful.
CommentedI am not sure how to get the current Jetty ServletContext for the WebSocketServerFactoryWe're talking about a test with a MockServletContext (i.e. No running Jetty server), right?I’d be open to suggesting API changes to improve testability if that would be helpful.Feel free to make suggestions. As far as I can see the WebSocketServerFactory requires a DecoratedObjectFactory and an Executor. The former can be detected from a ServletContext attribute while for the latter the ServletContext would have to implement the Jetty ContextHandler, so that would have to be a sub-class of MockServletContext at best. I am not quite sure how or where those customizations would be applied from. CommentedI'm taking a look at JettyRequestUpgradeStrategy as part of this andI'm working on an overhaul of this entire layer to bring it back to JSR356 by using an existing ServletContainerInitializer that has been present since Jetty 9.0.0In the meantime, where should I file bad assumptions that I come across.
Here in Jira or on github?Example: JettyWebSocketHandlerAdapter has an invalid close assumption. (onWebSocketClose is not after connection closed, its the same as JSR356 onClose, where the application can choose to finish up behaviors and close with a different code if they want). CommentedI'm tabling the moving of the implementation from what you have to using the SCI, for now.But the existing SCI should really be used to init the JSR356 container, and then you can use the normal ServletContext.getAttribute('javax.websocket.server.ServerContainer') behaviors to obtain the standard JSR356 container to add endpoints. Normal upgrade then proceeds via the standard HTTP requests into the server.Meanwhile, to address this, I'm working on a branch off of jetty-9.4.x to see if we can relax the ServletContextHandler and ContextHandler requirements a great deal. Commented, I had this ticket open in my browser and did not see your comments until now. Thanks for the fix related to this ticket and test environments.where should I file bad assumptions that I come across. Here in Jira or on github?This here is the issue tracker for the Spring Framework and it's the right place anything related to JettyRequestUpgradeStrategy and WebSocket overall.onWebSocketClose is not after connection closed, its the same as JSR356 onClose, where the application can choose to finish up behaviors and close with a different code if they wantPerhaps the name could have been better but the Javadoc does say:.
Invoked after the WebSocket connection has been closed by either side, or after a. transport error has occurred. Although the session may technically still be open,. depending on the underlying implementation, sending messages at this point is. discouraged and most likely will not succeed.We could improve that with an extra clarification that the status may still be changed, e.g. On Jetty and JSR-356.the existing SCI should really be used to init the JSR356 container, and then you can use the normal ServletContext.getAttribute('javax.websocket.server.ServerContainer') behaviors to obtain the standard JSR356 container to add endpoints.I addressed why this is not good enough for us under the. Perhaps respond / discuss there?
In general it would be great to coordinate this and the larger efforts related to your WebSocket API overhaul and HTTP/2. Note that we have this, and planned.
![Spring Spring](/uploads/1/2/5/5/125557656/867115775.png)
I need Websockets for real-time updates in my application. So i found this example and did it step by step. I was facing this issue while running websockets in IDE using embedded Jetty, fixed this after adding the below dependencies to pom.xml org.eclipse.jetty.websocketwebsocket-client9.3.4.RC0org.eclipse.jetty.websocketwebsocket-server9.3.4.RC0org.eclipse.jettyjetty-client9.3.4.RC0.