stomp-js / stompjs

Javascript and Typescript Stomp client for Web browsers and node.js apps
Apache License 2.0
738 stars 80 forks source link

ws does not work in the browser. Browser clients must use the native WebSocket #617

Closed damon112 closed 7 months ago

damon112 commented 7 months ago

My project is based on Vue 3, and the Node environment is v20. When I use the official example,such as the following code:

<script setup lang="ts">
import {Client} from '@stomp/stompjs';
import WebSocket from 'ws';
Object.assign(global, {WebSocket});
const client = new Client({
  brokerURL: 'ws://localhost:8080/gs-guide-websocket',
  onConnect: () => {
    client.subscribe('/topic/greetings', message =>
        console.log(`Received: ${message.body}`)
    );
    client.publish({destination: '/topic/greetings', body: 'First Message'});
  },
});
client.activate();
</script>

the first issue I encounter is that "global" is undefined. I added define: { global: 'globalThis' } in vite.config.ts to resolve the problem. Subsequently, I faced the issue mentioned in the title: "ws does not work in the browser. Browser clients must use the native WebSocket." I haven't been able to find a solution, and I'm unsure whether it's a problem with ws or stompjs.

When I remove the ws library ,delete the following two lines of code.

// import WebSocket from 'ws';
// Object.assign(global, {WebSocket});

and use the native WebSocket API, I am unable to connect to the WebSocket server. I believe there is no issue with my server-side, as when I use plain JS without Vue, as shown in the following code, it works:

 <script src="https://cdn.jsdelivr.net/npm/@stomp/stompjs@7.0.0/bundles/stomp.umd.min.js"></script>
...
const stompClient = new StompJs.Client({
    brokerURL: 'ws://localhost:8080/gs-guide-websocket'
});
kum-deepak commented 7 months ago

I do not know Vue. Based on the shared information:

Please provide the entire console output for me to provide a better answer.

damon112 commented 7 months ago

Thank you for your response. The issue has been resolved. By examining the server logs, it was discovered that the problem was due to the WebSocket connection request being intercepted by the server's CORS policy. Below are some code snippets, hoping they will be helpful for other beginners facing the same issue: Spring Boot side:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("*");
    }
}

VUE frontend:

<script setup lang="ts">
import {Client} from "@stomp/stompjs";
const client = new Client({
  brokerURL: 'ws://localhost:8080/gs-guide-websocket',
  onConnect: () => {
    client.subscribe('/topic/greetings', message =>
        console.log(`Received: ${message.body}`)
    );
    client.publish({
      destination: "/app/hello",
      body: JSON.stringify({'name': "hoho"})
    });
  },
});
client.activate();
</script>