Spring Boot应用程序中的Websocket - 获取403禁止
当我在eclipse(没有弹簧启动)中运行时,我可以使用sockjs/stompjs从客户端连接到websocket.
但是当我为websocket代码创建一个Spring启动jar(gradlew build)并运行java -jar websocket-code.jar时,我得到403错误连接到websocket.
我没有websockets的身份验证.我有一个CORS过滤器,并认为请求/响应中的所有标题正确.
下面是我的build.gradle
apply plugin: 'java'
apply plugin: 'spring-boot'
apply plugin: 'war'
sourceCompatibility = 1.7
version = '1.0'
repositories {
mavenCentral()
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE")
}
}
configurations {
compile.exclude module: "spring-boot-starter-tomcat"
}
dependencies {
compile "org.springframework:spring-web:$spring_version"
compile "org.springframework:spring-webmvc:$spring_version"
compile "org.springframework:spring-websocket:$spring_version"
compile "org.springframework:spring-messaging:$spring_version"
compile "org.springframework.boot:spring-boot-starter-websocket"
compile "org.springframework.boot:spring-boot-starter-web"
compile "com.fasterxml.jackson.core:jackson-databind:2.6.2"
compile "com.fasterxml.jackson.core:jackson-core:2.6.2"
compile "com.fasterxml.jackson.core:jackson-annotations:2.6.2"
compile "org.springframework.amqp:spring-rabbit:1.3.5.RELEASE"
compile("org.springframework:spring-tx")
compile("org.springframework.boot:spring-boot-starter-web:1.2.6.RELEASE")
compile("org.springframework.boot:spring-boot-starter-jetty:1.2.6.RELEASE")
testCompile group: 'junit', name: 'junit', version: '4.11'
testCompile …Run Code Online (Sandbox Code Playgroud) 我正在使用Spring websockets(STOMP作为子协议)和Sockjs开发消息传递应用程序.
我应该提供支持来发送消息中的文件.
根据这张票,sockjs不支持二进制数据,但STOMP确实如此.
我知道我们可以将图像转换为base64并通过stomp发送它,但我认为这不是最好的做法,因为有很多转换和开销.此外,我必须保存消息,所以要再次在服务器上保存这个base64编码文件我将不得不解码它们.
我有几个问题:
1)是否有通过sockjs + stomp发送图像/文件或转换为Base64的解决方法是唯一的方法?
2)这可能是一个非常愚蠢的问题,但根据这个问题,可以通过STOMP发送二进制数据(没有sockjs).没有sockjs支持后备有多难?
谢谢.
编辑:如果使用base64是唯一的选择,我宁愿发出POST请求来保存具有附件的消息,而不是使用base64编码.任何更好的想法?
我正在使用带有SockJS的Spring-Websockets 4.2.
由于客户端收到的消息可能非常大,我想使用部分消息.我的TextWebSocketHandler的子类确实覆盖supportsPartialMessages以返回true.但是,由于Spring创建的SockJsWebSocketHandler不支持部分消息,我仍然会收到错误code=1009, reason=The decoded text message was too big for the output buffer and the endpoint does not support partial messages.
作为一种变通方法,如描述我增加了缓冲区大小为1 MB 这里,但因为我要支持相当大量的客户端(〜2000年在同一时间),这需要太多的内存.
有没有办法使用SockJS的部分消息?
我正在尝试通过Spring webSocket在客户端和服务器之间建立连接,我正在通过此链接进行此操作.我希望Controller每隔5秒向客户端发送一个"hello",客户端每次都会将它附加到问候语框中.这是控制器类:
@EnableScheduling
@Controller
public class GreetingController {
@Scheduled(fixedRate = 5000)
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting() throws Exception {
Thread.sleep(1000); // simulated delay
System.out.println("scheduled");
return new Greeting("Hello");
}
}
Run Code Online (Sandbox Code Playgroud)
这是app.jsp中的Connect()函数:
function connect() {
var socket = new SockJS('/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.send("/app/hello", {}, JSON.stringify({'name': "connect"}));
stompClient.subscribe('/topic/greetings', function (message) {
console.log("message"+message);
console.log("message"+(JSON.parse(message.body)));
showGreeting(JSON.parse(message.body).content);
});
});
}
Run Code Online (Sandbox Code Playgroud)
当index.jsp加载并按下连接按钮时,只有一次它在问候语中发出问候语,我应该如何让客户端每隔5秒显示一个"hello"消息?
我在我的javascript客户端中使用stomp.js而不是SockJS.我正在使用websocket连接
stompClient.connect({}, function (frame) {
Run Code Online (Sandbox Code Playgroud)
stomp over sockJS连接有2个http请求:
客户端发送所有cookie.我也想发送自定义标头(例如XSRF标头),但没有找到办法做到这一点.将不胜感激任何帮助.
我正在阅读SockJS节点服务器.文件说:
WebSockets通常不能很好地与代理和负载均衡器配合使用.在Nginx或Apache之后部署SockJS服务器可能会很痛苦.幸运的是,最新版本的优秀负载均衡器HAProxy能够代理WebSocket连接.我们建议将HAProxy作为前线负载均衡器,并使用它来分离来自普通HTTP数据的SockJS流量.
我很好奇是否有人可以在这种情况下扩展HAProxy正在解决的问题?特别:
我是弹簧websocket的新手.我想将产品更改发送给客户.为此,我想按如下方式执行:客户端创建套接字连接并订阅目标:
var socket = new SockJS('/websocket');
var stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
stompClient.subscribe('/product/changes', function (scoredata) {
// We received product changes
});
});
//Send Ajax request and say server I want to know product with id=5 changes.
sendAjaxRequest(5);
Run Code Online (Sandbox Code Playgroud)
我已将弹簧应用程序配置如下:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/product/");
registry.setApplicationDestinationPrefixes("/app");
}
}
Run Code Online (Sandbox Code Playgroud)
现在我需要以下方法:
@RestController
public class ProductController {
@GetMapping("product-{id}")
public void startSubscribe(@PathVariable("id") Long …Run Code Online (Sandbox Code Playgroud) 我在使用websockets时遇到一些问题:
java.io.IOException: Broken Pipe我想知道的主要事项:
SpringMVC项目使用websockets; SockJS客户端和org.springframework.web.socket.handler.TextWebSocketHandler服务器端.
A JSON生成服务器端并发送给客户端.有时,我得到了java.io.IOException: Broken Pipe.我google/StackOverflowed很多,发现太多我不理解的东西,但原因可能是连接是关闭客户端而服务器仍然发送消息(例如,心跳).听起来不错吗?这种例外的其他原因是什么?客户端关闭连接的原因是什么(刷新或关闭选项卡除外)?
此外,有时客户端不会从服务器获取任何消息,尽管服务器应该发送它们.我在发送消息之前和之后进行登录,并打印两个日志语句.有谁知道为什么会发生这种情况?我在Chrome的控制台日志中没有错误.刷新页面不起作用,我需要重启spring项目...
如果您需要更多信息,请发表评论.
function connect() {
var socket = new SockJS('/ws/foo');
socket.onopen = function () {
socket.send(fooId); // ask server for Foo with id fooId.
};
socket.onmessage = function (e) {
var foo = JSON.parse(e.data);
// Do something with foo.
};
}
Run Code Online (Sandbox Code Playgroud)
服务器端
服务
@Service
public class FooService implements InitializingBean {
public void …Run Code Online (Sandbox Code Playgroud) 有没有澄清,如果我使用"简单代理",Spring Websocket + SockJS的/ topic,/ queue等之间有什么区别?例如,这里向Spring Websocket上的特定用户发送消息:当您的客户端订阅以/ user /开头的频道时,例如:/ user/queue/reply,您的服务器实例将订阅名为queue/reply-user的队列[会话ID]
我想以一种明确的方式理解这种转换背后的逻辑.
我有以下js代码:
stompClient.subscribe('/topic/clients', function (calResult) {
updateClientsTable(JSON.parse(calResult.body));
});
$.get("/clients", null);
Run Code Online (Sandbox Code Playgroud)
并遵循服务器代码(最后一行调用它):
@GetMapping(value = {"/clients"})
@ResponseBody
public void loadClients() {
brokerMessagingTemplate.convertAndSend("/topic/clients", clientService.getClientList());
}
Run Code Online (Sandbox Code Playgroud)
有时前端未命中的结果 $.get("/clients", null);
据我了解问题:在结果进入前端的那一刻,订阅不会发生.
如果把$.get("/clients", null);以下代码放在代码中 - 一切正常.
你能解释一下如何等待订阅吗?
sockjs ×10
spring ×6
websocket ×6
java ×5
stomp ×4
spring-boot ×3
javascript ×2
gradle ×1
haproxy ×1
spring-mvc ×1
stompjs ×1