How to programmatically disconnect user from peerServer - peerjs

I want to be able to programmatically disconnect user if the client.id and client.token does seems fishy (PeerServer).
How would I go about doing that inside the connection handler -
peerServer.on('connection', (client) => {
if(is_fishy(client)) {
// disconnected it.
}
});

The .on('connection') event passes a DataConnection object that you can use to disconnect a remote peer.
peerServer.on('connection', (client) => {
if (is_fishy(client)) {
client.close();
}
});

Related

Make promise calls with a fixed timeout

I am currently trying to make it check for a database connection. but it seems like the result, ie connection is pending.
I am looking to impliment a system where i can send an timeout input, where the promise would be rejected due to a fixed timeout.
Something like;
try {
start(timeout: 6000) // 6 secs timeout on promise. default, ie no params: 3sec
} catch(e) {
// failed due to, in this case, timeout, since there is no connection running, and the database is pending their promise.
}
How can i accomplish such timeout?
current running example gives the following:
connected to mongo Promise { <pending> }
starting server code:
const start = async () => {
console.log("connecting to database");
try {
console.log("Attempting to establish connection....");
var result = await mongoose.connect('mongodb://localhost/db',{useNewUrlParser: true});
console.log("connected to mongo",result);
return result;
} catch (error) {
console.log("failed to connect to mongo",error);
}
}
try {
start();
} catch(e) {
console.log("failed to start server",e);
throw new Error("failed to start server",e);
}

Xamarin Forms How to change Port or IPAddress of socket connection

I have a UWP (soon to be MacOS also) application that listens for incoming messages. The user can configure which IP Address and Port to listen on. Once the socket connection is listening, the user can also go back into the settings and change the IP Address or Port. I am trying to figure out how to shut down the existing listener and restart it using the new Port / IP Address when the user changes the values. Here is my code that starts the listener. Any help would be appreciated.
private static Socket iobj_listener;
public async static Task StartListening()
{
try
{
Debug.WriteLine("Point 1");
IPEndPoint localEndPoint = new IPEndPoint(ViewModelObjects.AppSettings.ServerIPAddress, ViewModelObjects.AppSettings.ServerPort);
// Create a TCP/IP socket.
iobj_listener = new Socket(ViewModelObjects.AppSettings.ServerIPAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
iobj_listener.Bind(localEndPoint);
iobj_listener.Listen(100);
ViewModelObjects.AppSettings.ListeningOnSocket = true;
while (true)
{
Debug.WriteLine("Point 2");
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Debug.WriteLine("Waiting for a connection on " + ViewModelObjects.AppSettings.ServerIPAddress.ToString() + "...");
iobj_listener.BeginAccept(
new AsyncCallback(AcceptCallback),
iobj_listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
finally
{
Debug.WriteLine("Point 3");
ViewModelObjects.AppSettings.ListeningOnSocket = false;
}
}
SO I could not find any quick answers so had to kind of figure this out on my own. If you see anything wrong with this, please let me know.
First of all I declared an e_Num as follows
public enum ge_SocketStatus
{
e_NotListening = 0,
e_Listening = 1,
e_Restart = 2
}
Then I added a StopListening function to my class that handles all my Socket communications and set the socket status to not listening as follows:
public static async Task StopListening()
{
try
{
if (iobj_listener.Connected)
{
//Wait till the connection ends or 30 seconds - this is so any last messages can be processed.
await Task.Delay(30000);
}
ViewModelObjects.AppSettings.SocketStatus = ge_SocketStatus.e_NotListening;
iobj_listener.Close(1);
}
catch (Exception ex)
{
App.AppException(ex);
}
}
I then use the value of this enum to know when to end the loop:
public async static Task StartListening()
{
try
{
Debug.WriteLine("Point 1");
IPEndPoint localEndPoint = new IPEndPoint(ViewModelObjects.AppSettings.ServerIPAddress, ViewModelObjects.AppSettings.ServerPort);
// Create a TCP/IP socket.
iobj_listener = new Socket(ViewModelObjects.AppSettings.ServerIPAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
iobj_listener.Bind(localEndPoint);
iobj_listener.Listen(100);
ViewModelObjects.AppSettings.SocketStatus = ge_SocketStatus.e_Listening;
while (ViewModelObjects.AppSettings.SocketStatus == ge_SocketStatus.e_Listening)
{
Debug.WriteLine("Point 2");
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Debug.WriteLine("Waiting for a connection on " + ViewModelObjects.AppSettings.ServerIPAddress.ToString() + "...");
iobj_listener.BeginAccept(
new AsyncCallback(AcceptCallback),
iobj_listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
finally
{
Debug.WriteLine("Point 3");
}
}
This line above
while (ViewModelObjects.AppSettings.SocketStatus == ge_SocketStatus.e_Listening)
used to be
while (true)
so the loop would never end.
One gotcha I found is in the AcceptCallback used in the BeginAccept function of my socket. In this code, I also had to detect if the socket was connected because this function is called one last time after the StartListening loop exits. At the point the socket is not connected so trying to do anything with is, such as EndAccept, causes the application to throw an exception. Below you can see where I added the line
if (listener.Connected)
in order to stop the code from crashing after I had closed the connection.
public static void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
//If we have shut down the socket don't do this.
if (listener.Connected)
{
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
Once all StopListening function ends and everything from the sockets is disconnected, I can call start listening again and open the socket on a different IPAddress and or Port.
I hope this helps as I could not find a good solution to this.

socket.io duplicate emit events on browser refresh

I'm running into an issue with my socket.io implementation and don't know how to solve it. I'm using pg_notify with LISTEN so when a certain value is modified in the db, it emits 'is_logged_in' to a certain client.
That in itself is working fine - my issue is when I refresh the page, socket.io disconnects the current socket_id, creates a new socket_id as usual, but when this happens, it's creating a second pgsql client instance and duplicating requests - fires the "logged_in" event 2x.
If I refresh the page again, and then manually fire the pg "logged_in" trigger, it will now emit 3 times etc. I have a leak.
const io = require('socket.io')();
const pg = require('pg');
io.on('connection', (socket) => {
const pgsql = new pg.Client({
(host, port, user, pass, db)
})
pgsql.connect()
pgsql.query("LISTEN logged_in");
pgsql.on('notification', function (data) {
socket.to(json.socket_id).emit('is_logged_in', { status:'Y' });
});
socket.on('disconnect', () => {
//pgsql.end();
});
});
I've tried killing the pgsql instance (in the socket.on disconnect) but for some reason the LISTEN stops working when I do that.
I've also tried moving the new pg.Client outside the io.on connection but when I refresh the page, the old socket_id disconnects, the new one connects, and it never executes the code to recreate the pg client.
Any ideas?
These are creating problems probably:
The pgsql instance is created on each socket connection request and is not being destroyed on disconnection
notification handler is not being removed on disconnection
I'm not much familiar with postgres, but I have worked extensively with socket. so, something like this should fix your issue:
const io = require('socket.io')();
const pg = require('pg');
const pgsql = new pg.Client({
(host, port, user, pass, db)
})
pgsql.connect();
io.on('connection', (socket) => {
pgsql.query("LISTEN logged_in");
const handler = function (data) {
socket.to(json.socket_id).emit('is_logged_in', { status:'Y' });
// You could also do pgsql.off('notification', handler) here probably
// or check if pgsql.once method is available as we need to call this handler only once?
}
pgsql.on('notification', handler);
socket.on('disconnect', () => {
pgsql.off('notification', handler);
//pgsql.end(); // Call it in server termination logic
});
});

Angular2 e2e test case with protractor throwing error

I have created my app with angular2-webpack-starter and i have used socket.io with it. I have created one common service to create socket connection and listen its method. this service is used and initialized after user is logged in. When app is running and i execute test case for login, i am checking url with below code :
browser.getCurrentUrl().then((url) => {
expect(url).toEqual('/dashboard');
});
The issue is when socket is connected its throwing error 'Timed out waiting for Protractor to synchronize with the page after 15 seconds' and if socket is not connected same test case is running without any error.
I'm not sure if connecting to the socket is actually make things take longer or not but if the 15 seconds isn't enough time, you can change the
allScriptsTimeout:timeout_in_millis in your protractor configuration file
protractor timeouts
So the solution I have found is:
(This is copied from here for your convenience. All credit goes to https://github.com/cpa-level-it
https://github.com/angular/angular/issues/11853#issuecomment-277185526)
What I did to fix the problem was using ngZone everywhere I have an observable that relies on socket.io.
So let's say you have this method in your service that gives you an observable on a socket.io.
private socket: SocketIOClient.Socket;
public getSocketIOEvents(): Observable<SocketIOEvent> {
if (this.socket == null) {
this.socket = io.connect(this._socketPath);
}
return Observable.create((observer: any) => {
this.socket.on('eventA', (item: any) => observer.next(new SocketIOEvent(item)));
this.socket.on('eventB', (item: any) => observer.next(new SocketIOEvent(item)));
return () => this.socket.close();
});
}
Then you need to use the ngZone service to tell Angular to create the socket outside the Angular 2 zone and then execute the callback of the Observable inside the Angular 2 zone.
import { NgZone } from '#angular/core';
constructor(
private socketService: SocketIOService, ,
private ngZone: NgZone) { }
ngOnInit() {
// Subscribe to the Observable outside Angular zone...
this.ngZone.runOutsideAngular(() => {
this.socketService
.getSocketIOEvents()
.subscribe(event => {
// Come back into Angular zone when there is a callback from the Observable
this.ngZone.run(() => {
this.handleEvent(event);
});
});
});
}
This way protractor doesn't hang waiting on the socket.

Wifi Direct - GO receives connection request

I have 2 P2P devices (android smartphones). They created a Wifi Direct Group. So, we have a Group owner and a Client. A third device appears, and wants to join the group sending a connection request to the GO. When this happens the GO BroadcastReceiver detects a disconnect. I would like to know if that is a normal behavior or I'm doing something wrong.
This is part of my BroadcastReceiver
else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION
.equals(action)) {
if (manager == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
WifiP2pInfo wifiP2pInfo = (WifiP2pInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
WifiP2pGroup wifiP2pGroup = (WifiP2pGroup) intent
.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
if (networkInfo.isConnected()) {
// we are connected with the other device, request connection
// info to find group owner IP
} else {
// It's a disconnect
}
} else if ....