我不明白如何在springboot应用程序中正确编写websocket测试用例。我有一个实现的类,我在中添加了这个处理程序:WebSocketHandlerWebSocketConfigurer
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(logWebSocketHandler() , "/test")
.addInterceptors(new HttpSessionHandshakeInterceptor())
.setAllowedOrigins("*");
}
@Bean
public LogWebSocketHandler logWebSocketHandler(){
return new LogWebSocketHandler();
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我在下面编写测试用例时,我得到一个异常:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration({App.class})
@WebAppConfiguration
public class LogsControllerTest {
private WebSocketContainer container;
@Before
public void setup() {
container = ContainerProvider.getWebSocketContainer();
}
@Test
public void testGetLog() throws Exception {
Session session = container.connectToServer(new TestEndpoint(),
URI.create("ws://127.0.0.1:8080/test"));
}
}
Run Code Online (Sandbox Code Playgroud)
异常::
javax.websocket.DeploymentException发起WebSocket连接的HTTP请求失败
我读到,如果我设置ws://127.0.0.1:8080/test/(末尾斜杠)它将起作用,但它不起作用。
我做错了什么?
我想打开一个带有"webapp/socket.do"路径的websocket端口.当我使用SockJS并尝试通过代码启动调用时
var socket = new SockJS('/webapp/socket.do');
stompClient = Stomp.over(socket);
stompClient.connect({}, ...
Run Code Online (Sandbox Code Playgroud)
默认情况下,SockJS会在给定路径的末尾添加"/ info".我想知道为什么?这可以改变或预防吗?
当它与Spring MVC一起使用并且具有与DispatcherServlet类似的url模式映射时< url-pattern >*.do</url-pattern>,这将返回404错误.它被阻止是因为sockJS将"/ info"字符串添加到给定的URL.
Spring web.xml servlet映射代码:
<servlet-mapping>
<servlet-name>dispatch-servlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
Run Code Online (Sandbox Code Playgroud)
有谁知道sockJS在那里尝试什么,为什么?
我已经使用Java EE 7提供的api实现了一个WebSocket.此外,我已经实现了一个请求我的WebSocket没有任何问题的客户端.为了确保在执行某些代码更改时这仍然有效,我想实现测试,这些测试也可以在构建服务器上运行,例如Jenkins CI,而不仅仅是在本地.我正在使用maven.
这是我的服务器端点:
import javax.enterprise.context.ApplicationScoped;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@ApplicationScoped
@ServerEndpoint("/example")
public class WebSocket {
private final Set<Session> sessions = Collections.synchronizedSet(new HashSet<>());
@OnOpen
public void open(Session session) {
sessions.add(session);
}
@OnClose
public void close(Session session) {
sessions.remove(session);
}
@OnError
public void onError(Throwable error) {
//TODO do something
}
@OnMessage
public void handleMessage(String message, Session session) throws IOException {
session.getBasicRemote().sendText("Hello "+message+"!");
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的客户端端点:
import javax.websocket.*;
import java.io.IOException;
import java.net.URI;
@ClientEndpoint …Run Code Online (Sandbox Code Playgroud) 我正在尝试在Java服务器和JavaScript客户端之间建立连接,但我在客户端遇到此错误:
与'ws://127.0.0.1:4444 /'的WebSocket连接失败:连接在收到握手响应之前关闭
它可能保持在OPENNING状态,因为connection.onopen从不调用该函数.该console.log('Connected!')不会被调用.
有人能告诉我这里出了什么问题吗?
服务器
import java.io.IOException;
import java.net.ServerSocket;
public class Server {
public static void main(String[] args) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(4444)) {
GameProtocol gp = new GameProtocol();
ServerThread player= new ServerThread(serverSocket.accept(), gp);
player.start();
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
System.exit(-1);
}
}
}
Run Code Online (Sandbox Code Playgroud)
ServerThread
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerThread extends Thread{
private Socket socket = null; …Run Code Online (Sandbox Code Playgroud) 当我的服务器发生内部错误时,如何正确关闭 websocket 并向客户端提供干净、信息丰富的响应?在我当前的情况下,客户端在连接时必须提供一个参数,并且我正在尝试处理 OnOpen 收到的不正确或丢失的参数。
这个例子表明我可以在 OnOpen 中抛出一个异常,它最终会调用 OnError ,我可以在其中给出原因和消息来关闭。它有点工作,但客户端只收到 EOF、1006、CLOSE_ABNORMAL。
另外,因为我没有找到其他讨论,所以我无法说出什么可能是最佳实践。
我正在使用 JSR-356 规范,如下所示:
@ClientEndpoint
@ServerEndpoint(value="/ws/events/")
public class WebSocketEvents
{
private javax.websocket.Session session;
private long token;
@OnOpen
public void onWebSocketConnect(javax.websocket.Session session) throws BadRequestException
{
logger.info("WebSocket connection attempt: " + session);
this.session = session;
// this throws BadRequestException if null or invalid long
// with short detail message, e.g., "Missing parameter: token"
token = HTTP.getRequiredLongParameter(session, "token");
}
@OnMessage
public void onWebSocketText(String message)
{
logger.info("Received text message: " + message); …Run Code Online (Sandbox Code Playgroud) 所以我有一个Websocket Session,它从服务器读取信息.但是,如果我切断了它完全接收的信息,大约一分钟后它将停止接收新信息,并且即使重新打开服务器的输出也不会做任何事情.
我以为是WebSocketContainer方法
setDefaultMaxSessionIdleTimeout(Long time)
Run Code Online (Sandbox Code Playgroud)
会解决我的问题,所以我把它设置为
container.setDefaultMaxSessionIdleTimeout(86400000L);
Run Code Online (Sandbox Code Playgroud)
我认为这意味着它将继续运行长达1天的不活动状态.
然而事实并非如此,它在一分钟不活动后就停止了.下面是我正在使用的代码,也许有人可以让我知道我做错了什么:
public void run(String... args) throws Exception {
log.info("Starting...");
log.info("-- API URL: {}", apiUrl);
log.info("-- API Token: {}", apiToken);
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.setDefaultMaxSessionIdleTimeout(86400000L);
ClientEndpointConfig config = ClientEndpointConfig
.Builder.create()
.configurator(new CustomConfigurator(apiToken))
.build();
try {
session = container.connectToServer(ConsumerClient.class, config, URI.create(apiUrl));
} catch (DeploymentException de) {
log.error("Failed to connect - DeploymentException:", de);
} catch (IOException ioe) {
log.error("IOException:", ioe);
}
if (this.session == null) {
throw new RuntimeException("Unable to connect to endpoint.");
}
log.info("Max …Run Code Online (Sandbox Code Playgroud) 对于客户,我们使用Tomcat 8.0.29构建了一个 HTML5 websocket 应用程序。如果我们从我们的网络或我们的家庭网络启动应用程序,一切正常。但是如果客户从他的网络启动应用程序,一段时间后 websocket 会因错误而停止。这可能会在 5 或 20 分钟后发生。
我们已经在使用和不使用 SSL 以及两台不同的服务器上对其进行了测试。只有在客户网络中,连接会因错误而中断。
我们还使用Tomcat 中包含的 websocket echo 示例进行了测试。和我们的 websocket 一样。一段时间后,websocket 因错误而停止。但前提是我们从客户网络启动应用程序。
当 echo 示例因错误而停止时,以下消息将写入 server.log
08-Dec-2015 10:20:37.757 SEVERE [http-apr-8081-exec-2] org.apache.tomcat.websocket.pojo.PojoEndpointBase.onError No error handling configured for [websocket.echo.EchoAnnotation] and the following error occurred
java.io.IOException: Unexpected error [730,054] reading data from the APR/native socket [1,639,490,672] with wrapper [org.apache.tomcat.util.net.AprEndpoint$AprSocketWrapper@231e01e4:1639490672].<br/>
at org.apache.coyote.http11.upgrade.AprServletInputStream.doRead(AprServletInputStream.java:133)<br/>
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.read(AbstractServletInputStream.java:124)<br/>
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:51)<br/>
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:183)<br/>
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)<br/>
at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)<br/>
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:669)<br/>
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2500)<br/>
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2489)<br/>
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)<br/> …Run Code Online (Sandbox Code Playgroud) 我正在尝试连接到安全的Web套接字以使用API.以下是源代码.托管环境配置是JRE 1.7和Tomcat 7.
import java.net.URI;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import org.apache.log4j.Logger;
@ClientEndpoint
public final class SocketRateFeed
{
private static final Logger logger = Logger.getLogger(SocketRateFeed.class);
private Session sessionWS;
public static void startContainer()
{
try
{
URI wsURI = new URI("wss://websocket.abc.xyz/?api_key=qwerty&user_id=ASDF");
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(new SocketRateFeed() , wsURI);
}
catch(Exception exp)
{
logger.error(exp.getMessage() , exp);
}
}
....other annotated methods
}
Run Code Online (Sandbox Code Playgroud)
这是堆栈跟踪.
28-02-2017 11:24:37 localhost-startStop-1 ERROR SocketRateFeed.startContainer(30) …Run Code Online (Sandbox Code Playgroud) 请原谅我提出这个新手问题,但我很困惑,并且显然不理解如何使用托管在HTTPS. 我在网上找到的所有内容都让我的问题多于答案。
我的HTTPS网站上有一个使用 Java 代码托管的 Websocket 服务器。
这是我的WebsocketServer.java文件:
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class WebsocketServer extends WebSocketServer {
private static final Logger logger = LogManager.getLogger(WebsocketServer.class);
private static int TCP_PORT = 6868;
private static Set<WebSocket> conns;
public WebsocketServer() {
super(new InetSocketAddress(TCP_PORT));
conns = new HashSet<>();
}
@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
conns.add(conn);
logger.info("New connection from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
logger.info("Size of …Run Code Online (Sandbox Code Playgroud) java-websocket ×10
java ×9
websocket ×5
java-ee-7 ×1
javascript ×1
javax ×1
keystore ×1
openshift ×1
signalr ×1
signalr-hub ×1
sockjs ×1
spring ×1
spring-boot ×1
ssl ×1
tomcat ×1
tomcat8 ×1
tomee ×1
tomee-7 ×1
ws ×1