WebSocket is not defined with NuxtJS - javascript

So I want to make a web socket client using a VueJs using NuxtJs framework, this is My component
export default {
data() {
return {
connection: null,
}
},
created() {
console.log("Starting connection to WebSocket Server")
this.connection = new WebSocket("wss://echo.websocket.org")
this.connection.onmessage = function(event) {
console.log(event);
}
this.connection.onopen = function(event) {
console.log(event)
console.log("Successfully connected to the echo websocket server...")
}
},
head() {
return {
title: 'Web Socket',
meta: [
{
hid: 'description',
name: 'description',
content: 'Web socket'
}
]
}
}
}
And I got this message
I'm using Ms Edge for the browser, I tried using a vue-native-socket, and other socket package, but still get the same error 'Websocket not defined'

I'm no Websocket expert, but to my knowledge, this is something available only on client side.
You may try to follow up this answer: https://stackoverflow.com/a/67751550/8816585
created() {
if (process.client) {
// the code in this block will only run on client side
console.log("Starting connection to WebSocket Server")
this.connection = new WebSocket("wss://echo.websocket.org")
this.connection.onmessage = function(event) {
console.log(event);
}
this.connection.onopen = function(event) {
console.log(event)
console.log("Successfully connected to the echo websocket server...")
}
}
}
This will prevent the code written inside of the created() hook to be triggered on both server and client side (hence the error on the server). Because created() is available on both server and client side, as explained here: https://nuxtjs.org/docs/2.x/concepts/nuxt-lifecycle/

Related

Not able to communicate through websocket from amazon connect

I'm integration amazon connect platform to maintain a two-way flow communication in our own chatbot where customer will be the user in our platform and agents will be there on amazon connect platform to communicate. I'm using websockets for the communication now but it is giving me Forbidden error. Details are mentioned below
Initially, I have used aws-sdk and #aws-sdk/client-connectparticipant library to make the connection with aws and then multiple SDKs in order are used further to send the messages.
startChatContact -> Used AWS library to make the connection with AWS and then using it to retrieve participation token
createParticipantConnection -> Using participation token to retrieve connection token from this sdk using Type: [ 'CONNECTION_CREDENTIALS' ]
sendEvent -> Using connection token and ContentType: 'application/vnd.amazonaws.connect.event.connection.acknowledged' to send the event
sendMessage -> After sending the event, sending the message with connection token and ContentType: 'text/plain'
import * as AWS from 'aws-sdk';
import * as AWSConnectParticipant from "#aws-sdk/client-connectparticipant";
private messageText = "";
private connectionToken = "";
private connectParticipant = new AWSConnectParticipant.ConnectParticipant({
credentials: {
accessKeyId: '...',
secretAccessKey: '...'
},
region: '...'
});
// It will get called when user sends a message on the chat window
public sendMessage(text: string): void {
this.messageText = text || "";
if (this.connectionToken) {
this.sendEventOnAWSConnect();
} else {
this.startChatContact();
}
}
startChatContact() {
const connect = new AWS.Connect({
accessKeyId: '...',
secretAccessKey: '...',
region: '...'
});
const params = {
ContactFlowId: '...',
InstanceId: '...',
ParticipantDetails: {
DisplayName: 'Customer'
}
};
connect.startChatContact(params, (err: any, data: any) => {
if (data) {
this.createParticipantConnection(data);
}
});
}
createParticipantConnection(startChatContactRes: any) {
const params = {
ParticipantToken: startChatContactRes.ParticipantToken,
Type: [ 'CONNECTION_CREDENTIALS' ]
};
this.connectParticipant.createParticipantConnection(params, (err: any, data: any) => {
if (data) {
this.connectionToken = data.ConnectionCredentials.ConnectionToken;
this.sendEventOnAWSConnect();
this.checkAgentMessage(data.Websocket.Url);
}
});
}
sendEventOnAWSConnect() {
const params = {
ConnectionToken: this.connectionToken,
ContentType: 'application/vnd.amazonaws.connect.event.connection.acknowledged'
};
this.connectParticipant.sendEvent(params, (err: any, data: any) => {
if (data) {
this.sendMessageOnAWSConnect();
}
});
}
sendMessageOnAWSConnect() {
const params = {
ConnectionToken: this.connectionToken,
Content: this.messageText,
ContentType: 'text/plain'
};
this.connectParticipant.sendMessage(params, (err: any, data: any) => {
if (data) {
console.log("Agent connected");
}
});
}
It is working fine as expected. I'm able to send messages on amazon connection with the following code. But I'm facing some issues on receiving agent messages back. I have search for any events which I can trigger on my end or any webhook, but unable to find anything on the same.
Issue on 1st method: Not a good approach. Looking for a better solution
So, I have used polling technique initally where I have used getTranscript SDK from #aws-sdk/client-connectparticipant and calling the api on every 2 seconds to check for any new agent messages but I'm looking for a better method now on the same.
Issue on 2nd method: getting connect.core.getWebSocketManager() as undefined
After exploring, I have also found that there is an onMessage event, which I can trigger using amazon-connect-streams and amazon-connect-chatjs library after creating agent session but
connect.core.getWebSocketManager() as undefined. Also, code after connect.contact is not getting executed, so I have commented that also. I have also created customer session similarly but there also **onMessage **event is not getting triggered. I'm calling its method i.e. checkAgentMessage after I get response from createParticipantConnection method successfully since I'm using contact id, participant id and participant token in checkAgentMessage method, which I'm getting from createParticipantConnection method. Below is the code.
import "amazon-connect-streams";
import "amazon-connect-chatjs";
createParticipantConnection(startChatContactRes: any) {
const params = {
ParticipantToken: startChatContactRes.ParticipantToken,
Type: [ 'CONNECTION_CREDENTIALS' ]
};
this.connectParticipant.createParticipantConnection(params, (err: any, data: any) => {
if (data) {
this.connectionToken = data.ConnectionCredentials.ConnectionToken;
this.sendEventOnAWSConnect();
this.checkAgentMessage(data);
}
});
}
checkAgentMessage(startChatContactRes: any): void {
// for type customer
// const customerChatSession = connect.ChatSession.create({
// chatDetails: {
// contactId: startChatContactRes.ContactId,
// participantId: startChatContactRes.ParticipantId,
// participantToken: startChatContactRes.ParticipantToken,
// },
// type: connect.ChatSession.SessionTypes.CUSTOMER
// });
// for type agent
// connect.contact(contact => {
// if (contact.getType() !== connect.ContactType.CHAT) {
// // applies only to CHAT contacts
// return;
// }
// alternative: if you want control over the args of `connect.ChatSession.setGlobalConfig()` and `connect.ChatSession.create()`
// contact.onAccepted(() => {
const agentChatSession = connect.ChatSession.create({
chatDetails: {
contactId: startChatContactRes.ContactId,
participantId: startChatContactRes.ParticipantId,
participantToken: startChatContactRes.ParticipantToken,
},
options: { // REQUIRED
region: "...", // REQUIRED, must match the value provided to `connect.core.initCCP()`
},
type: connect.ChatSession.SessionTypes.AGENT, // REQUIRED
websocketManager: connect.core.getWebSocketManager() // REQUIRED
})
agentChatSession.onMessage(event => {
console.log("event", event);
});
// });
// });
}
I have checked if I can set connect.core.getWebSocketManager() from somewhere, but got nothing help on the same.
Issue on 3rd method: getting Forbidden as error or message
I have also come across another solution and that is from web sockets. So, I'm implementing the same but there I'm getting error as Forbidden
I have changed my createParticipantConnection function with something as below:
createParticipantConnection(startChatContactRes: any) {
const params = {
ParticipantToken: startChatContactRes.ParticipantToken,
Type: [ 'WEBSOCKET' ]
};
this.connectParticipant.createParticipantConnection(params, (err: any, data: any) => {
if (data) {
let socket = new WebSocket(data.Websocket.Url);
socket.onopen = function(e) {
console.log("[open] Connection established");
console.log("Sending to server");
socket.send("My name is John");
};
socket.onmessage = function(event) {
console.log("event", event);
console.log(`[message] Data received from server: ${event.data}`);
};
socket.onclose = function(event) {
if (event.wasClean) {
console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
} else {
// e.g. server process killed or network down
// event.code is usually 1006 in this case
console.log('[close] Connection died');
}
};
socket.onerror = function(error) {
console.log(`[error]`);
};
// this.connectionToken = data.ConnectionCredentials.ConnectionToken;
// this.sendEventOnAWSConnect();
// this.checkAgentMessage(data);
}
});
}
Changed Type from CONNECTION_CREDENTIALS to WEBSOCKET to retrieve the websocket url. Getting output on the same as:
[open] Connection established
Sending to server
event MessageEvent {...}
[message] Data received from server: {"message": "Forbidden", "connectionId":"...", "requestId":"..."}
It is throwing Forbidden as error or message. Please let me know if there is anything I have left which needs to be also implemented or I have done anything wrong here. Also please let me know, if anybody have the solution for the issue on 2nd method or if there is any other method to retrieve agent messages as well.
After calling CreateParticipantConnection, you need to send a subscribe message. You'll then start receiving messages & events on the websocket.
From https://docs.aws.amazon.com/connect-participant/latest/APIReference/API_CreateParticipantConnection.html :
For chat, you need to publish the following on the established websocket connection:
{"topic":"aws/subscribe","content":{"topics":["aws/chat"]}}

socket.io on client side not listening to server events

The socket have to listen to the server when i send a new message.
The messages arrive because when i refresh the page i can see them.
Server side socket i know is working find because in other frontend app the same client socket is working find.
This socket is called every time the user select a new chat in the web.
Here is the socket service in my app:
import openSocket from "socket.io-client";
function connectToSocket() {
return openSocket("http://localhost:8080");
}
export default connectToSocket;
And here is the code executed when user select a chat:
// how i am importing the socket
import openSocket from "../../Services/socket-io"
async function fetchMessages(ticketId) {
try {
const { data } = await api.get("/messages/" + ticketId, {
params: { pageNumber },
});
if (ticketId === data.ticket.id) {
await loadMessages(data, ticketId);
}
listenMessages(ticketId);
} catch (err) {
Toast.ToastError("Error trying to load messages");
}
};
function listenMessages(ticketId) {
const socket = openSocket();
socket.on("connect", () => socket.emit("joinChatBox", ticketId));
socket.on("appMessage", (data) => {
if (data.action === "create") {
console.log(data);
}
if (data.action === "update") {
console.log(data);
}
});
}
What i already tried:
Use the same socket version both in client and server (3.0.5).
Calling listenMessages every time a message is sent.
socket.io-client version 4.

How to call a function from PWA registerServiceWorker in VUE

I'm using VUE 3 with PWA and I need to call some functions from the registerServiceWorkers.js instead of console logging them, like when an update found or when updated.
this is the service worker:
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready () {
console.log(
'App is being served from cache by a service worker.\n' +
'For more details,'
)
},
registered () {
console.log('Service worker has been registered.')
},
cached () {
console.log('Content has been cached for offline use.')
},
updatefound () {
console.log('New content is downloading.')
},
updated () {
console.log('New content is available; please refresh.')
},
offline () {
console.log('No internet connection found. App is running in offline mode.')
},
error (error) {
console.error('Error during service worker registration:', error)
}
})
}
any suggestion???
i used this last time:
https://dev.to/drbragg/handling-service-worker-updates-in-your-vue-pwa-1pip
offers you the ability to inform the user for new updates and allows caching them then

Create a tcp client in the vue.js

I try to create a tcp client in vue.js. I use this code below. but it gives to me error. that error is net.Socket() is not a constructor. How can I solve this problem or How can I create a client for tcp with another way. help please.
import net from 'net'
export default {
data() {
return {
ip: '192.168.1.118',
port: '8085',
message: 'test message',
socket: null
}
},
mounted() {
const socket = new net.Socket()
this.socket = socket
socket.on('data', (data) => console.log(data.toString()))
},
methods: {
connect() {
this.socket.connect(this.port, this.ip)
},
sendMessage() {
this.socket.write(this.message)
}
}
}

How to reconnect a websocket connection after manual close - Vue

Here's my methods to open/close socket connection:
methods: {
connect () {
this.$socket.onopen = () => {
this.status = 'connected'
this.$socket.onmessage = ({data}) => {
this.$socket.send(this.message)
console.log({ event: "Recieved message", data })
}
}
this.$socket.onclose = (e) => {
console.log('Socket is closed. Reconnect will be attempted in 1 second.')
setTimeout(() => {
this.connect()
}, 1000)
}
},
disconnect () {
this.$socket.close()
this.status = 'disconnected'
}
}
I'm not using socket.io etc, just built in Websocket object.
When i manually call disconnect () method - it closes the connection as expected, but when i send message again - it says that connection is closed. Since i call connect () in a mounted, then it won't reconnect if i don't refresh the page.
I've tried using watcher:
watch: {
'$socket': 'connect'
}
But no effect. Is there a way to watch for websocket connection status? If it's closed - call connect (), if it's error'ed - call connect () to reconnect it.
Your connect() method does nothing to "reconnect" to the WebSocket server. So calling this.connect() simply rewrites your onopen handler.
You have to take the steps necessary to reconnect to the WebSocket server. The most excellent answer to this question does a great job of explaining a great structure for your code:
vue: emitting global events from websocket listener
Unfortunately, it doesn't answer your specific question. So I've forked the sandbox from that answer and added the modified code below that allows you to achieve your goal.
import Vue from "vue";
const url = "wss://echo.websocket.org";
let socket;
const emitter = new Vue({
methods: {
send(message) {
if (1 === socket.readyState) socket.send(message);
},
close() {
if (1 === socket.readyState) {
emitter.$emit("message", "Closing Socket.");
socket.close();
socket = null; // prevent memory leak
}
},
connect() {
socket = new WebSocket(url);
socket.onmessage = function(msg) {
emitter.$emit("message", msg.data);
};
socket.onerror = function(err) {
emitter.$emit("error", err);
};
emitter.$emit("message", "Openning Socket.");
}
}
});
emitter.connect();
export default emitter;
To see how this service is used, check out index.js in the running sample is here:
https://codesandbox.io/s/ry4993q654
You should check the close status code before reconnecting.
e.code === 1e3 || e.code === 1001 || e.code === 1005

Categories

Resources