I'm creating a test application to know a little more about websocket, in this application I create a chat system between client and user.
I'm using:
SQLServer;
Nestjs;
Socket.io;
React;
In my backend I configured a websocket Adapter to keep the default settings for all Gateways
import { IoAdapter } from '#nestjs/platform-socket.io';
import { ServerOptions, Socket } from 'socket.io';
export class SocketAdapter extends IoAdapter {
createIOServer(
port: number,
options?: ServerOptions & {
namespace?: string;
server?: any;
},
) {
const server = super.createIOServer(port, {
...options,
cors: {
origin: '*',
},
pingInterval: 1000,
pingTimeout: 10000,
serveClient: true,
} as ServerOptions);
return server;
}
}
On my front, socket.io is configured as follows:
import socketIOClient from "socket.io-client";
export const socket = socketIOClient(import.meta.env.VITE_APP_URL_SOCKETIO, {
auth: {
token: ""
},
transports: ['websocket', 'polling'],
forceNew: true,
reconnection: true,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000,
reconnectionAttempts: 5
});
I got to test several settings for pingInterval, pingTimeout, reconnectionDelay, forceNew but they all return the same problem.
The problem that occurs is, when the client is making a connection with the server, if for some reason the internet connection has fluctuated (remove the cable) and then returns, the SERVER should not disconnect the socket from the client immediately, thus having a waiting time for its reconnection.
Starting the server on my computer, I could see that the reconnection time works normally
enter image description here
However, when sending the server application to an instance on AWS, Heroku or railway, none of them maintain the connection so that the socket can reconnect, when the connection goes offline, the server immediately shows the disconnected socket.
Because of this I thought it would be some wrong configuration in AWS with Load Balancer, but using heroku the same thing happened
enter image description here
I tried following some settings I found, but none worked either.
https://medium.com/containers-on-aws/scaling-a-realtime-chat-app-on-aws-using-socket-io-redis-and-aws-fargate-4ed63fb1b681
AWS application load balancer and socket.io
socket.io on aws application load balancer
What can be done so that the connection remains in the socket for a short time without disconnecting?
Related
My socket IO URL is replaced by weird string like http://%22 on my VM (Centos) it's not cause by Nginx or something because I've tested it using my development mode and it is working normally on Windows machine.
Here is the console log output
As you can see the url is become like https://%22https/ws/?EIO=4&transport=polling&t=O5iOwlU
and the correct url must be like https://example.com/ws/?EIO=4&transport=polling&t=O5iOwlU
It never happened before, it just happened today. and this is my snippets of my code:
const socketOptions = {
reconnection: true,
rejectUnauthorized: false,
path: '/ws',
}
if (process.env.VUE_APP_STATUS === 'development') {
socketBase = `${process.env.VUE_APP_SOCKET}`
} else {
socketBase = `${process.env.VUE_APP_SOCKET_PRODUCTION}`
}
// Vue.use(VueSocketIo, Socket)
Vue.use(
new VueSocketIo({
debug: true,
connection: socketBase,
vuex: {
store,
actionPrefix: 'SOCKET_',
},
options: socketOptions
}),
)
I've tried everything but it still doesn't work. I'm using this lib for my socket io client Vue-Socket.io
I'm looking to keep my elasticsearch's client connection alive. I've been using the elastic client and had some great success with it when indexing and searching its datastore, but I want to be able to create a connection to my elasticsearch's nodes and preserve the connection so that I don't need to continuously create a new connection for every time I POST to it.
Having looked at the documentation I see there's a keep-alive feature for the swagger documentation but I've created my client using nodejs and have had no such luck finding any feature to do so.
my client looks something like this:
const client = new Client({
auth: {
username: 'aSecret',
password: 'alsoASecret',
},
node: 'localhost:9000',
maxRetries: 3,
requestTimeout: 15000,
});
and my index is very simple right now:
await client.index({
index: 'my-datastore'
refresh: true,
body: eventData,
});
How can I keep my index Connection alive so that I can send multiple events to my datastore without having to connect and reconnect?
There is a keepAlive config option in the Client's constructor.
And its a boolean value. Reference
keepAlive: Should the connections to the node be kept open forever? This behavior is recommended when you are connecting directly to Elasticsearch.
var elasticsearch = require('elasticsearch');
var client = new elasticsearch.Client({
auth: {
username: 'aSecret',
password: 'alsoASecret',
},
node: 'localhost:9000',
maxRetries: 3,
requestTimeout: 15000,
keepAlive: true
});
When using the REST client extension in VSCode eg.
Send Request
GET http://localhost:4200/dashboard
###
I get following error :
Connection is being rejected. The service isn’t running on the server,
or incorrect proxy settings in vscode, or a firewall is blocking requests.
Details: RequestError: connect ECONNREFUSED 127.0.0.1:4200
How can I change my http-proxy to 4200 instead of 127.0.0.1:4200 ?
The solution that works for me, it's to change the server hostname with a string (hostname: "127.0.0.1").
Deno/TS/Rest client Extension vscode
app.ts
import { Drash } from "https://deno.land/x/drash#v1.4.3/mod.ts";
import { Api } from "./api.ts";
const server = new Drash.Http.Server({
response_output: "application/json",
resources: [Api],
});
server.run({
hostname: "127.0.0.1", // Just here !
port: 1854,
});
console.log("Server running...");
api.ts
// #ts-ignore
import { Drash } from "https://deno.land/x/drash#v1.4.3/mod.ts";
export class Api extends Drash.Http.Resource {
static paths = ["/"];
public GET() {
this.response.body = `Hello World! (on ${new Date()})`;
return this.response;
}
}
req.http
GET http://localhost:1854/ HTTP/1.1
OR
GET http://127.0.0.1:1854/ HTTP/1.1
I am having a kind of strange problem when I trying to establish a single mongodb connection to a db with the mongodb nodejs native driver in the version 3.6.0.
My idea is to have just one connection opened through all the client session and reuse it in the different routes I have in my express server, when I hit it the first time the getDatabase function it creates two connections and after that one of it closes and one stands idle, but when I use a route, the second get opened again (it is like one connection just stays there and do nothing).
I just want to have one connection opened in my pool.
If you see the commented code i was testing with those options but none of them worked for me.
Pd: when I set the socketTimeoutMS to 5000ms just one connection is created but it auto-closes and reopen each 5000ms, which is weird (it reopen itself even when I don't use the connection).
All of this problem happen when I set the useUnifiedTopology to true (I can't set it to false because is deprecated and the other topologies will be removed in the next version of mdb ndjs driver)
Here is an image with the strange behaviour
The code is:
import { MongoClient, Db } from 'mongodb';
import { DB_URI } from '../config/config';
// This mod works as DataBase Singleton
let db: Db;
export const getDataBase = async (id: string) => {
try {
if (db) {
console.log('ALREADY CREATED');
return db;
} else {
console.log('CREATING');
let client: MongoClient = await MongoClient.connect(`${DB_URI}DB_${id}`, {
useUnifiedTopology: true,
/* minPoolSize: 1,
maxPoolSize: 1,
socketTimeoutMS: 180000,
keepAlive: true,
maxIdleTimeMS:10000
useNewUrlParser: true,
keepAlive: true,
w: 'majority',
wtimeout: 5000,
serverSelectionTimeoutMS: 5000,
connectTimeoutMS: 8000,
appname: 'myApp',
*/
});
db = client.db();
return db;
}
} catch (error) {
console.log('DB Connection error', error);
}
};
The driver internally creates one connection per known server for monitoring purposes. This connection is not used for application operations.
Hence, it is expected that you would get two connections established.
Strange behavior in Node with TLSSocket and tls.connect.
var port = 7000;
var host = '94.125.182.252'; //freenode
var tls = require('tls');
var net = require('net');
var socket = new net.Socket();
var secure;
secure = new tls.TLSSocket( socket, {
isServer: false,
rejectUnauthorized: false
});
// edit (left out of original post, but present in my test code, whoops)
secure.connect( {
port: port,
host: host
});
secure.setEncoding( 'utf8' );
secure.on( 'connect' , function() {
console.log( 'connected' );
})
.on( 'secureConnect', function() {
console.log( 'secure connect' );
})
.on( 'error', function( e ) {
console.log( 'error', e );
})
.on( 'data', function( data ) {
console.log( data );
});
if ( secure.isPaused() ) {
console.log( 'socket was paused' );
secure.resume();
}
This doesn't even attempt to connect and no error messages are produced. I have wireshark monitoring and there is no activity captured.
A different approach:
secure = tls.connect( {
rejectUnauthorized: false,
host: host,
port: port,
socket: socket
});
Same story, nothing captured, no errors. If I remove the socket: socket aspect above it will connect. This makes some sense as the docs state that if the socket option is specified it will ignore port and host. The above works on my previous Node version( 0.12.7).
If I want to use the existing socket I have to tell it to connect before calling tls.connect.
socket.connect( {
port: port,
host: host
});
secure = tls.connect( {
rejectUnauthorized: false,
socket: socket
});
This doesn't seem proper.
Passing a connecting socket to tls.TLSSocket( socket, ...) seems to have no effect.
The 'connect' event is fired but I imagine that is not related to TLSSocket.
I could not get tls.TLSSocket(...) to work on previous Node iterations.
Stepping through with node debug did not expose any obvious problems.
The options for net.Socket([options]) don't seem to accept a port or host for configuring until you try to connect, and trying to connect before passing to tls.connect seems counter intuitive. It would suggest that is not the intended usage.
So my questions would be:
What am I doing wrong with tls.TLSSocket() or perhaps is it a bug?
Am I correct to assume that passing an existing socket into tls.connect() is for already established connections switching protocol? If not, whats the proper way to assign a port and host?
Edit:
As per suggestion:
secure = tls.connect( {
rejectUnauthorized: false,
socket: socket
});
socket.connect( {
port: port,
host: host
});
This works.
secure = new tls.TLSSocket( socket , {
isServer: false,
rejectUnauthorized: false
});
socket.connect( {
port: port,
host: host
});
Unfortunately this does not work. A 'connect' event is emitted, never a 'secureConnect' and never any other events or data.
In your first two (non-working) examples, you only created a socket and never started actually connected it. Add a socket.connect(); at the end of your original code and it should work fine.
tls.connect() when passed a plain socket, does not actually call socket.connect(); internally, it merely sets up to start listening for data on the socket so it can decrypt incoming data properly.