• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Node.js + Socket.io + PHP - przekazywanie id zalogowanego użytkownika

Aruba Cloud PRO i VPS, Openstack, VMWare, MS Hyper-V
+1 głos
1,195 wizyt
pytanie zadane 3 lutego 2016 w JavaScript przez Janek Czerwiński Nowicjusz (160 p.)

Witam, piszę aplikację w node.js gdzie używam socket.io aby w czasie rzeczywistym aktualizować listę powiadomień zalogowanego użytkownika, która umieszczona jest na aplikacji PHP. Mam problem, ponieważ loguję się na stronę i chcę przekazać to id zalogowanego użytkownika przez PHP do node. Próbowałem to zrobić juz w ten sposób: 

(klient)

var loggeduser_Id = {{ id usera z twiga }};

socket.emit('user id', loggeduser_Id);

(serwer)

io.sockets.on('connection', function(socket) {
          socket.on('user id', function(data) {
                   var user_id = data;
                      
                     //jakieś działania
         }

}

Tylko chyba ta metoda nie jest zbyt bezpieczna (żeby ktoś nie wbił się na powiadomienia innego użytkownika - np. curl) i wydajna. Czytałem też na internecie o współdzieleniu sesji pomiędzy node a PHP używając redisa, zainstalowałem to nawet, ale nie wiem czy warto instalować całe oprogramowanie tylko po to, aby przekazać jedną zmienną. Jest jakiś sposób aby to w miarę prosty, bezpieczny i najbardziej wydajny sposób przekazać?

Drugie pytanie dotyczy samych socketów, mianowicie jeśli zrobię tak jak w przykładzie powyżej, to musiałbym dla każdego usera robic socket.emit(inna nazwa, data); Np.

(klient)

var loggeduser_Id = {{ zmienna z twiga }}

socket.emit('user id', loggeduser_Id);

    socket.on('pw'+loggeduser_Id, function(data) {
        $('.pw').html(data);
        count_pw = parseInt(data);
    });

(serwer)

io.sockets.on('connection', function(socket) {
        socket.on('user id', function(data) {
                var user_id = data;
                 io.sockets.emit('pw'+user_id, jakas_zmienna);
        }
}

I gdybym miał np. 1000 użytkowników zalogowanych, to czy robienie 1000 różnych emitów jest wydajne? A jeśli nie to czy jest jakiś inny sposób aby przekazać to jednym nie nadpisując przy tym tego emita?

Nie hejtujcie, jeśli napisałem coś głupiego, siedzę w node niecały tydzień dopiero :p .

1 odpowiedź

+3 głosów
odpowiedź 3 lutego 2016 przez Comandeer Guru (583,120 p.)
wybrane 3 lutego 2016 przez Janek Czerwiński
 
Najlepsza
Redis nie jest głupim pomysłem. Innym, w tym guście, jest po prostu zrobienie REST API, które będzie odpytywane zarówno przez PHP, jak i node.
komentarz 8 lutego 2016 przez Comandeer Guru (583,120 p.)
Socket.io można podpiąć pod expressa. Inna rzecz: nie bardzo wiem po co Ci express…
komentarz 8 lutego 2016 przez Janek Czerwiński Nowicjusz (160 p.)
Nie mogłem znaleźć żadnych modułów do sesji innych niż do expressa. A używam tego w podobny sposób do tego co jest tu:

https://gist.github.com/mscdex/9507b0d8df42e0aec825
komentarz 11 lutego 2016 przez Janek Czerwiński Nowicjusz (160 p.)

Wszystko działało, aż tu nagle błąd:

/var/www/html/node/node_modules/express-session/session/store.js:77
 var expires = sess.cookie.expires
                           ^
TypeError: Cannot read property 'expires' of undefined
    at RedisStore.Store.createSession 

Kod:

app.use(cookieParser());
var sessionMiddleware = session({
    store: new RedisStore({
        host: '127.0.0.1',
        port: 6379,
        pass: 'redis',
        prefix: 'session:php:'
    }),
    name: 'PHPSESSID',
    secret: 'keepo',
    resave: true,
    saveUninitialized: true
});

O co chodzi? Jak wywalam connect-redis (czyli to new RedisStore) to błędu nie ma.

Mam też taki problem, że node raz czyta ładnie sesję z php, a raz nie pomimo tego, że kodu nie zmieniam. 

komentarz 11 lutego 2016 przez Comandeer Guru (583,120 p.)
Średnio Ci pomogę, bo od dawna w tym nie siedziałem.
komentarz 28 lutego 2016 przez piotrusg19 Początkujący (280 p.)

Jeśli rozwiązałeś problem to gratuluję, jeśli nie to spróbuj może takiej konstrukcji obiektu sesji:

app.use(cookieParser());
app.use(expressSession({
	resave: true, saveUninitialized: true,
	secret: 'SECRET',
	cookie: {maxAge: 60*60*1000}, 
	store: new mongoStore({
	  	url:'mongodb://' + userDb + ':' + passDb + '@' + mongoHost + '/' + database,
	  	autoRemove: 'interval',
	  	autoRemoveInterval: 1,
  		}),
  }));

Co prawda ja robiłem to dla mongo ale z redisem nie powinno być problemu. I jeszcze kilka rzeczy:

- dlaczego odpalasz serwer http skoro masz już expressa, przecież on załatwia wszystko związane z www (no, prawie) ?

- czy ten redis potrzebny Ci jest tylko jako magazyn dla sesji, jeśli tak to możesz wykorzystać swoją główną bazę danych (jakiś mysql czy inny postgress) ?

- po gwizdek Ci ten php, do obsługi klienta?

- jeśli masz problem z tym samym numerem portu dla socket.io to może lepiej wykorzystać jakiś inny port dla niego (np. 3001) ? Oczywiście musisz to potem uwzględnić w kliencie.

To wszystko powyżej to nie jest żadna krytyka, mam więc nadzieję że się nie obrazisz

Podobne pytania

0 głosów
2 odpowiedzi 586 wizyt
pytanie zadane 10 lipca 2016 w JavaScript przez Damian Makieła Nowicjusz (200 p.)
–4 głosów
1 odpowiedź 275 wizyt
pytanie zadane 10 lipca 2016 w JavaScript przez Damian Makieła Nowicjusz (200 p.)
+1 głos
0 odpowiedzi 94 wizyt
pytanie zadane 6 października 2020 w JavaScript przez poldeeek Mądrala (5,990 p.)

90,319 zapytań

138,924 odpowiedzi

311,159 komentarzy

60,027 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...