I am creating a chat application using socket.io along with vue js. My connection code looks like this:
import Vue from 'vue'
import VueSocketIO from 'vue-socket.io'
import SocketIO from "socket.io-client"
const io=SocketIO('https://example.com:8443');
Vue.use(new VueSocketIO({
debug: true,
connection: io
}))
There is no error in connection, which means the connection is done I think. And then I added on connection evening like this:
io.on('connection', socket => {
console.log("hai");
})
But this function is not calling when connection done. So to check I changed the port number, then the connection fails, so connection is done properly I think.
By referring to some other code, I just added like
sockets: {
connect: function() {
console.log('socket connected')
}
}
also.But didn't work.I am new to vue.How can i solve this.Thanks in advance
My console showing the follows
Vue-Socket.io: Received socket.io-client instance
vue-socketio.js?5132:10 Vue-Socket.io: Vuex adapter enabled
vue-socketio.js?5132:10 Vue-Socket.io: Vuex socket mutations disabled
vue-socketio.js?5132:10 Vue-Socket.io: Vuex socket actions enabled
vue-socketio.js?5132:10 Vue-Socket.io: Vue-Socket.io plugin enabled
Related
[GET] /proizvodi/9?fbclid=PAAaY2n3yQfX-Wzxs5pTMWeP9nMUkdIv2V4qg8kObIDQgUAdPnwLtWEr4ICYg_aem_AT5iXQ0y2WTFTVjFAkqIfOf-vx44GuIUXoJKxT5IunSH48Cf1QVjlfC8Q1rKapxuuR9daAL70GWwpLZ_rINriwy815oEYfwfXFvOuh3HvHBvhWRFkVdfeQom7PK6UZvTp0s
02:39:09:44
2023-01-26T01:39:09.507Z f0d6641c-416c-4c0a-ba67-c59890f6f936 ERROR [2023-01-26T01:39:09.507Z] #firebase/firestore: Firestore (9.15.0): Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds.
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.
2023-01-26T01:39:09.539Z efb98c51-3cde-4791-981f-5d22145fe3c0 ERROR Unhandled Promise Rejection {"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"TypeError: fetch failed","reason":{"errorType":"TypeError","errorMessage":"fetch failed","cause":{"errorType":"Error","errorMessage":"Client network socket disconnected before secure TLS connection was established","code":"ECONNRESET","host":"translate.googleapis.com","port":443,"localAddress":null,"stack":["Error: Client network socket disconnected before secure TLS connection was established"," at connResetException (node:internal/errors:711:14)"," at TLSSocket.onConnectEnd (node:_tls_wrap:1593:19)"," at TLSSocket.emit (node:events:525:35)"," at endReadableNT (node:internal/streams/readable:1359:12)"," at process.processTicksAndRejections (node:internal/process/task_queues:82:21)"]},"stack":["TypeError: fetch failed"," at fetch (/var/task/node_modules/undici/index.js:105:13)"," at process.processTicksAndRejections (node:internal/process/task_queues:95:5)"]},"promise":{},"stack":["Runtime.UnhandledPromiseRejection: TypeError: fetch failed"," at process.<anonymous> (file:///var/runtime/index.mjs:1194:17)"," at process.emit (node:events:525:35)"," at emit (node:internal/process/promises:149:20)"," at processPromiseRejections (node:internal/process/promises:283:27)"," at process.processTicksAndRejections (node:internal/process/task_queues:96:32)"]}
Unknown application error occurred
Runtime.Unknown
App works perfectly on the localhost, but on when deployed to vercel, I am getting these functions crashes now and then, seems like it's random. It's happening on all urls.
This is really a bummer since it's an e-commerce website and it's ruining my conversion rate.enter image description here
I tried changing the adapter in svelte.config.js to #sveltejs/adapter-vercel hoping it would work but to no avail.
Vercel uses cloud functions which lose web socket connections when they are frozen (as they are after a few minutes of not running). To ensure it works you can create a new connection for each request (so inside load function or GET function).
// $lib/firebase.js
import { initializeApp } from "firebase/app";
const firebaseConfig = {
// FIREBASE_CONFIGURATION
};
export const getFirebaseApp = () => initializeApp(firebaseConfig);
// src/routes/example/+page.server.ts
import { getFirestore } from "firebase/firestore";
import { getFirebaseApp } from "$lib/firebase";
export const load = async ({ params, url }) => {
const app = getFirebaseApp();
const db = getFirestore(app);
// use database and give a response
})
Another idea is would be to use #google-cloud/firestore serverside instead of #firebase/firestore because it is specifically for the backend (see this tutorial).
I am new to vue and maybe I miss some fundamental concept here but I am not able to force my vue app to call the backend from the frontend server origin (ip:port). It seems that the API calls arriving from the client IPs instead - cause an issue that the backend CORS control cannot work.
I try to create a simple hello-world app and host a separate backend and frontend server in a docker container on a NAS running at local network. The ip of the NAS on the local network is 192.168.0.150. I mapped the port: 5000 to the backend and 6080 to the frontend.
I use python fastAPI as a backend and vuejs as a frontend. everyting works fine if I allow all the origins in the fastapi.middleware.cors setting :
Backend - fastapi.middleware.cors settings :
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
#app.get("/")
def home(request:Request):
client_host = request.client.host
client_port= request.client.port
return {"message": "Hello, World!","client_host": client_host,"client_port":client_port }
'''
frontend/src/main.js - axios setting
axios.defaults.withCredentials = true;
axios.defaults.baseURL = 'http://192.168.0.150:5000/'; // the FastAPI backend
frontend/view - api call:
<template>
<div>
<p>{{ msg }}</p>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'Ping',
data() {
return {
msg: '',
};
},
methods: {
getMessage() {
axios.get('/')
.then((res) => {
this.msg = res.data;
})
.catch((error) => {
console.error(error);
this.msg = error.msg;
});
},
},
created() {
this.getMessage();
},
};
</script>
regardless of how I host the Vue app (with dev server -npm run serve- or after a build with a HTTP server) the message above in the tmeplate shows the ip of the devices on the network from where the page is opened and not the frontend (192.168.0.150:6080) as I would expect.
So that if I set the fastapi middleware to restrict the origins then the API call fails:
allow_origins=["http://192.168.0.150:6080/"]
I also tried to set up a proxy, based on this: https://techformist.com/vuejs-proxy-error-for-backend-connection/ but keep the same behavior.
would you please help with what I miss here?
is my understanding wrong that the API should feel that it is called from the frontend host:port rather than the clients?
I am making my first steps with websockets in my application.
My frontend is using vue.js while my backend uses flask.
In my component I wrote this.
created() {
console.log('Starting connection to WebSocket Server');
// this.connection = new WebSocket('wss://echo.websocket.org');
this.connection = new WebSocket('wss://192.168.0.22:5000');
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...');
};
},
In my flask app.py besides other stuff I have this
app = Flask(__name__)
socketio = SocketIO(app)
CORS(app)
"""Socket.IO decorator to create a websocket event handler"""
#socketio.on('my event')
def handle_my_custom_event(json, methods=['GET', 'POST']):
print('received my event: ' + str(json))
socketio.emit('my response', json, callback=messageReceived)
def messageReceived(methods=['GET', 'POST']):
print('message was received!!!')
if __name__ == "__main__":
socketio.run(app, debug=True)
In my browser I get the error that firefox could not make a connection to wss://192.168.0.22:5050. I already tried the frontend with the websocket from a tutorial which is commented out now.
I am not sure, which url I should use for my own backend or what I have to add there.
Sorry if this is obvious but I am a complete beginnern.
Thanks in advance!
EDIT:
In chrome the error I receive is "WebSocket connection to 'wss://192.168.0.38:5000/' failed: WebSocket opening handshake timed out"
Also as I saw this error when trying out stuff, maybe this question could be relevant? vue socket.io connection attempt returning "No 'Access-Control-Allow-Origin' header is present" error even when origins have been set
so the part for the socket which i ended up using for the client/component:
import io from 'socket.io-client';
created() {
// test websocket connection
const socket = io.connect('http://192.168.0.38:5000');
// getting data from server
// eslint-disable-next-line
socket.on('connect', function () {
console.error('connected to webSocket');
//sending to server
socket.emit('my event', { data: 'I\'m connected!' });
});
// we have to use the arrow function to bind this in the function
// so that we can access Vue & its methods
socket.on('update_on_layouts', (data) => {
this.getAllLayouts();
console.log(data);
});
},
The Flask server code stayed as shown above. Additionally here is an example from my flask server to emit the update_on_layouts socketio.emit('update_on_layouts', 'success')
Intro
Most of you will probably ask "Why?", why am I doing this stack? The reason is that initially I created the project in Nuxtjs + expressjs. But my PM wanted me to not distribute my source code to our client so I decided to bundle my code up into a single .exe file with electron. I tried using pkg but I couldn't figure out how to compile everything exactly.
The problem
The problem I am having with socket.io-client is that I want to be able to move the exe file to a different machine, and have socket.io connect to the socket.io server on that machine dynamically. Changing machines would mean that the IP of the server will be different, so whenever the user opens the webpage for that server, the socket.io-client would connect to the proper server. It works when I build the app from my current machine but when moved to lets say a VM then this is the response I get when I access the page:
ServiceUnavailableError: Response timeout
at IncomingMessage.<anonymous> (C:\Users\LIANG-~1\AppData\Local\Temp\nscAD47.tmp\app\resources\app.asar\node_modules\connect-timeout\index.js:84:8)
at IncomingMessage.emit (events.js:182:13)
at IncomingMessage.EventEmitter.emit (domain.js:442:20)
at Timeout._onTimeout (C:\Users\LIANG-~1\AppData\Local\Temp\nscAD47.tmp\app\resources\app.asar\node_modules\connect-timeout\index.js:49:11)
at ontimeout (timers.js:425:11)
at tryOnTimeout (timers.js:289:5)
at listOnTimeout (timers.js:252:5)
at Timer.processTimers (timers.js:212:10)
To further elaborate on what I am trying to do, lets say I compile the code on my current machine with the private IP of 192.168.0.104 (this runs perfectly), I want to move the exe file to another machine with the private IP of 192.168.0.105 (Accessing the webpage from this server gives the above error).
Technology used
The technology that I am using is nuxt.js created with express template, socket.io, and vue-socket.io-extended.
What I have tried
I have tried checking for reconnect events or timeout events, when these events are triggered then I call socket.connect(process.env.WS_URL) which doesn't work. I believe that when I packaged the electron app, it makes the plugin data immutable. I couldn't figure out someway to change the URL to the address of the machine.
import Vue from 'vue'
import io from 'socket.io-client'
import VueSocketIO from 'vue-socket.io-extended'
export default ({ store }) => {
// process.env.WS_URL = 'http://192.168.0.12:3000'
const socket = io(process.env.WS_URL, { transports: 'websocket' })
socket.on('timeout', () => {
socket.connect(process.env.WS_URL)
})
Vue.use(VueSocketIO, io(process.env.WS_URL, { transports: 'websocket' }), { store })
}
What I have right now
I created a socket.io plugin for nuxtjs to implement into my app, the plugin looks like this:
import Vue from 'vue'
import io from 'socket.io-client'
import VueSocketIO from 'vue-socket.io-extended'
export default ({ store }) => {
// process.env.WS_URL = 'http://192.168.0.12:3000'
Vue.use(VueSocketIO, io(process.env.WS_URL, { transports: 'websocket' }), { store })
}
I expect the socket.io-client to connect to the correct private IP of where the exe file is located. But Request Timeout is received, even though when I output the process.env.WS_URL is actually the new address.
EDIT: After further testing, seems like the socket.io plugin is fixed, after the build process. So changing the process.env.WS_URL wouldn't have any effect. Is there a way to change the URL for socket.io even after nuxtjs finished building?
(I wanted to comment this but I can't)
Anyway, are you sure you the information in the edit is true?
I use Nuxt.js with Electron and also the vue-socket.io. I use an argument for calling the executable as the socket.io address:
This is specific for electron
global.sharedObject = { socketIOAddress: process.argv[1] }
and this is my nuxt plugin file for vue-socket.io:
import Vue from 'vue'
import VueSocketIO from 'vue-socket.io'
import { remote } from 'electron'
export default ({ store }) => {
Vue.use(new VueSocketIO({
debug: true,
connection: remote.getGlobal('sharedObject').socketIOAddress
vuex: {
store,
actionPrefix: 'SOCKET_',
mutationPrefix: 'SOCKET_'
}
})
)
}
So while the code might not be exactly what you want Nuxt doesn't have to be build again for it. Maybe the environment variables didn't change right when you tried? You should try with a argument as well perhaps.
Also important: ssr: false in the nuxt config for the vue-socket.io plugin.
The solution I came up with is by using an environmental variable. First have the variable set as localhost:3000 or whatever your server's local address is. I would use electron-store to keep a config.json file of all my settings including the server IP. Before my server starts up, I read the config file and change the server address set previously. Then I use it as follows:
import Vue from 'vue'
import io from 'socket.io-client'
import VueSocketIO from 'vue-socket.io-extended'
export default ({ app, store }) => {
Vue.use(VueSocketIO, io(app.$env.WS_URL), { store })
}
NOTE: WS_URL is the environmental variable name.
I am working with a react-native application that involves socket.io. I have installed socket.ion successfully and imported it in my component like:
import React, { Component } from 'react';
import io from 'socket.io-client/dist/socket.io';
const connectionConfig = {
jsonp: false,
reconnection: true,
reconnectionDelay: 100,
reconnectionAttempts: 100000/// you need to explicitly tell it to use websockets
};
socket = io('http://192.168.1.100:3001', connectionConfig);
type Props = {};
export default class Socket extends Component<Props> {
constructor(){
super();
socket.emit("Button",'pressed')
socket.on('userid',(id)=>{
this.setState({userid:{id}});
Alert.alert(id);
})
}
And the code for my server side using express is:
io.on('connection', function(socket){
console.log(socket.id);
socket.on('Button',function(data){
console.log("ButtonPressed");
});
socket.emit('userid',socket.id);
})
What is strange, after like every 1.5s the server console logs a different socket.id when i ran the application on an android device. I assume the socket.io connects successfully but again disconnects in the 1.5s i mentioned such that the socket.emit and socket.on event don't get to be executed.I have tried many options provided but cannot get the right way to fix this. Please if you know a work-around i highly appreciate. Thank you.
I realised on android if you use the option transports: ['websocket'] and you are in the development mode, then first enable the debug remotely by shaking your phone and sockets will work fine for you. So basiclly you should have something like
import io from 'socket.io-client';
const connectionConfig = {
jsonp: false,
reconnection: true,
reconnectionDelay: 100,
reconnectionAttempts: 5000,
transports: ['websocket']/// you need to explicitly tell it to use websockets
};
socket = io('http://192.168.1.100:3001', connectionConfig);