rodgc / ngx-socket-io

Socket.IO module for Angular
MIT License
261 stars 90 forks source link

how send extra data on connection?? #12

Closed santiagoalmeidabolannos closed 4 years ago

santiagoalmeidabolannos commented 6 years ago

i hope solve a problem like this https://stackoverflow.com/questions/4743592/send-additional-data-on-socket-connection

jasminexie commented 5 years ago

I'm assuming that you do this exactly like how you would in socket.io-client.

angular client:

import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';

const config: SocketIoConfig = { url: 'http://localhost:8988', options: {query: "param1=value1&param2=value2"} };

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    SocketIoModule.forRoot(config)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

express server:

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server ,{
    cookie: false, // some custom config here
    pingTimeout: 30000,
    pingInterval: 2000
});

io.sockets.on('connection', function (socket) {
  const query = socket.handshake.query;

  socket.on('event', function() { ... })
}

// query['param1'] = value1
// query['param2'] = value2
monurakkaya commented 5 years ago

@jasminexie what if params come from localstorage or websql?

jasminexie commented 5 years ago

@monurakkaya Socket.io requires you to initialize the socket upon construction. You can create a service that extends the socket service and perform custom initialization in it - which is basically what you would do anyway with the pure socket.io-client module in an Angular service. In my opinion the library is just a wrapper of socket.io-client's most basic functions with the benefit of easily managing multiple connections in multiple Angular modules - if you're not doing that, you'll be fine using vanilla socket.io-client.

ngx-socket-io:

@Injectable()
export class CustomSocket extends Socket {

    constructor() {
        const param = window.localStorage.getItem("key");
        super({ url: 'http://url_two:portTwo', options: { ... } });
    }

}

socket.io-client:

import * as io from 'socket.io-client';

@Injectable()
export class ChatService {

    socket: SocketIOClient.Socket;

    constructor() {
        const param = window.localStorage.getItem("key");
        socket = io.connect('http://localhost:8988', {query: "..."});
    }

}
monurakkaya commented 5 years ago

@jasminexie thanks for the explanation. But i'm using this package with @ionic/storage so i can't get token synchronously..

let token = this.storage.get('token')
      .then(data => {
        return data
      })

also i need to inject this storage module somewhere to reach ionic/storage.. normally i do it on service or provider's constructor. I couldn't figure out how to do that. Should i use localstorage to keep only token? What would advice?

Art2058 commented 5 years ago

@jasminexie same

sandeepsuvit commented 5 years ago

This worked for me ngx-socket-io:

@Injectable()
export class CustomSocket extends Socket {

    constructor(
        // Has got implementation to fetch the token from localstorage
        private authService: AuthService
    ) {
        super({ url: 'http://url_two:portTwo', options: {} });

        // Set token as part of the query object
        this.ioSocket.query = {
            token: (() => this.authService.getAccessToken() ? this.authService.getAccessToken().token : '')()
        };
    }

}

express server:

io.sockets.on('connection', async function (socket) {
    const token = socket.handshake.query.token;

    // Use the token to extract user information
    const auth_user: any = await jwt.verify(token, process.env.MY_SECRET);

    socket.on('event', function() { ... })
}
Loown commented 4 years ago

Someone found a solution ?? can't send my token that I get from ionic storage

turtle0x1 commented 4 years ago

Would also like to know!

Helveg commented 4 years ago

Something like this should work:

import {Socket, SocketIoConfig } from 'ngx-socket-io';

@Injectable({providedIn: 'root'})
export class AsyncSocketService {
  constructor() { }

  public createAsync(Observable<SocketIoConfig> config$) {
    return config$.pipe(map(config => new Socket(config)));
  }
}

You could use this as follows:

  this.asyncSocketService.createAsync({url: ..., options: {
    query: {token: this.tokenService.getToken()}
  }}).subscribe(
    socket => {
      console.log("Socket created", socket);
    }
  )

The trick is to create the socket only once the asynchronous configuration has been fetched: I don't think that's possible using the dependency injection approach, but you can just use the constructor.

ctfrancia commented 4 years ago

It's been 2 years, so just to clean the clutter I'm going to close this issue, If you still have issues please open up a new one