I am writing a web application in Nuxt 3 and want to integrate a SockJs over Stomp
websocket. Now I have written the component...
<template>
<div>
<h1>Test</h1>
</div>
</template>
<script lang="ts" setup>
import {useRouter, ref} from "#imports";
import SockJS from "sockjs-client";
import {Stomp} from "@stomp/stompjs";
let consoleText = ref<string>("");
interface ConsoleMessage {
messageContent: string,
user: string,
}
const props = defineProps<{
originURL:string,
publicURL:string,
privateURL:string
}>();
let stompClient: any = null;
function connect() {
const socket = new SockJS(props.originURL);
stompClient = Stomp.over(socket);
stompClient.connect({}, function () {
stompClient.subscribe(props.publicURL, function (message: { body: string; }) {
showMessage(JSON.parse(message.body));
});
stompClient.subscribe(props.privateURL, function (message: { body: string; }) {
showMessage(JSON.parse(message.body));
});
});
}
function showMessage(message: ConsoleMessage) {
consoleText.value = "\n" + message.messageContent + "\n";
}
connect();
</script>
I have imported @stomp/stompjs
and sockjs-client
via yarn add
. What do I have to change in the nuxt.config.ts
to make it so that the application loads the modules.
Edit:
Following the advice given by nur_iyad
I attempted to write a plugin
import {defineNuxtPlugin} from "nuxt/app";
import SockJS from "sockjs-client";
import {CompatClient, Stomp} from "@stomp/stompjs";
import {Message} from "~/composables/display";
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.provide('sock', () => new NuxtSockJs())
})
declare module '#app' {
interface NuxtApp {
$sock (): NuxtSockJs
}
}
export class NuxtSockJs {
stompInstance: CompatClient | null;
constructor() {
this.stompInstance = null;
}
connect(originURL:string,
subscribeURLs:Array<string>,
displayMessage: (message: Message) => any): void {
const socket = new SockJS(originURL);
let stompClient: CompatClient = Stomp.over(socket);
stompClient.connect({}, function () {
for(const subscribeURL of subscribeURLs) {
stompClient.subscribe(subscribeURL, function (message: { body: string; }) {
displayMessage(JSON.parse(message.body));
});
}
});
this.stompInstance = stompClient;
}
sendMessage(sendURL: string, message: Message):void {
(this.stompInstance)!.send(sendURL, {}, JSON.stringify(message));
}
}
This does not work and just throws the following error:
Uncaught ReferenceError: global is not defined
at node_modules/sockjs-client/lib/utils/browser-crypto.js
After a long hunt for an answer I have found the solution.
It is literally just importing the module into any TS activated component, in my case I packaged the SockJS into a composable
import {CompatClient, Stomp} from "@stomp/stompjs";
import {Message} from "~/composables/display";
import SockJS from "sockjs-client";
export class NuxtSockJs {
stompInstance: CompatClient | null;
isConnected: boolean;
constructor() {
this.stompInstance = null;
this.isConnected = false;
}
connect(originURL:string,
subscribeURLs:Array<string>,
displayMessage: (message: Message) => any): void {
const socket = new SockJS(originURL);
this.stompInstance = Stomp.over(socket);
this.stompInstance.debug = () => {};
this.stompInstance.connect({}, () => {
for(const subscribeURL of subscribeURLs) {
this.stompInstance!.subscribe(subscribeURL, (message) => {
displayMessage(JSON.parse(message.body));
});
}
});
this.isConnected = true;
}
sendMessage(sendURL: string, message: Message):void {
(this.stompInstance)!.send(sendURL, {}, JSON.stringify(message));
}
}
For anybody interested as to why SockJS would still not work, the following has to be added to the nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{children: 'var global = window;'}
]
}
}
});
Hope this helps anybody suffering from the issues I was :))