logux / server

Build your own Logux server or make a proxy between a WebSocket and an HTTP backend in any language
https://logux.org/
MIT License
454 stars 108 forks source link

Is logux good for real-time CRM & Asterisk integration? #53

Closed finkvi closed 6 years ago

finkvi commented 6 years ago

Hi, Martians! The question is in subject... logux looks very nice:

  1. I have cross tab communication by default. It's necessary when client gets incoming call, because user has many opened tabs, but I have to show only one notification or popup.

  2. I clearly separate actions by users. Users are just telephone extensions.

  3. Telephone events (Asterisk, AMI) push to client very often, but I want to know only last state, this option keepLast can help me

  4. Web Sockets inside, its is that i really needed

What disadvantages vs clear WS Server on NodeJS with custom logic + WS and React front? Speed? What else? Thx

ai commented 6 years ago

Hi. The main problem is that it is very young project. We still need more production tests of it.

Can your clients create a actions? Do you need to merge this actions?

finkvi commented 6 years ago

Now is young, tomorrow will be standard) No, browser clients doesn't send messages to server and I think merge is not a problem

ai commented 6 years ago

In this case Logux will work without any problem. It is a simple case. Just don't forget to mark actions with meta.channel and subscribe clients to the channels.

If you are looking an alternatives, try socket.io. Pure Web Socket is too low level.

finkvi commented 6 years ago

Thx, for help and fast opinion

For the benefit of others, I also researched:

Soket.io + Intercom.js (for cross tab socket)- but for my task very slow WS + wormhole.js (for cross tabs socket) - good, but trouble with tabs in FF and IE

I'll try to create demo with logux server + logux client with react and test it for performance

ai commented 6 years ago

Performance tests will be very good. We didn't test it for performance.

If you need the fastest way without conflict resolution and offline support:

  1. Use logux-client instead of logux-redux
  2. Use store: new MemoryStore () option in Logux Client.
finkvi commented 6 years ago
  1. Yes, I try to do it with pure React

  2. I added this option in my client, but nothing changes) const logux = new CrossTabClient({ credentials: token.content, subprotocol: '1.0.0', server: server.content, userId: user.content, store: new MemoryStore() }); logux.start(); I still see actions in Local Storage

image

And how will one cross tab socket work with such approach?

ai commented 6 years ago

localStorage is used for tab synchronization, not for storing actions (since it is very slow storage). We use IndexedDB as storage if you didn't change it in store option.

finkvi commented 6 years ago

Now I'm confused) Sorry for stupid questions.

My server adds actions and delete previous: app.log.add( { type: 'CHANGE_CALL_STATUS', callStatus: arrStatus[i] }, { keepLast: 'app/lastCallStatus', users: ['vfink_user']} );

My client catches this actions: logux.on('add', (action, meta) => this.handleCallStatus(action, meta));

We use IndexedDB as storage if you didn't change it in store option.

Why do I see change records in Local Storage as in the screenshot?

I din't change store option, my server definition is: ` const Server = require('logux-server').Server; const app = new Server(

Server.loadOptions(process, { subprotocol: '1.0.0', supports: '1.x', root: __dirname, port: 8082, host: process.env.IP || "0.0.0.0" }) ); `

ai commented 6 years ago

Now I'm confused) Sorry for stupid questions

There is no stupid questions. Especially, when the project doesn't have docs 😅

Why do I see change records in Local Storage as in the screenshot?

localStorage shows you how browser tabs talk to each other and leader tab notify other tabs about new actions

So you see not a storage, but just cross-tab communications

I din't change store option, my server definition is

Server stores actions in memory be default.

To be honest, next Logux Client 0.3 will store it in the memory too. IndexedDB will be used only in special cases.

My client catches this actions

It is just explanation. Don't worry if it sounds a little complicate. You do right now correctly and don't need to change client.

Note, that reasons and keepLast doesn't send by network. Server and clients have different reasons and keepLast for the same actions (for security reasons).

If you want to keep actions in client memory, use:

client.log.on("preadd", (action, meta) => {
  meta.keepLast = …
})

But do you need to keep actions in the memory? If you process action immediately and do not need to load actions in the future (for instance, to recalculate state later for Redux time travel), you can remove action after processing (just by not setting reasons or keepLast).

finkvi commented 6 years ago

Especially, when the project doesn't have docs

But the fastest support, thx!

So you see not a storage, but just cross-tab communications

Ok, now clear, as on the slide https://youtu.be/3LecnX1hjyw?t=966

But do you need to keep actions in the memory?

After all I'm not sure) I have a simple requirement:

telephone server generate events very fast, for example, just for example:

const arrStatus = [
    'Calling', //Call is coming to operator SoftPhone
    'PickUp', //Operator starts talking
    'CallEnded', //Operator ends talking, HangUp
    'CDR' //Call ends
  ];

If I have network troubles or not fast client machine... I want to react only the last event, because it's very strange to open client view in CRM when call was ended. In future I really need no such actions, but any time I must know that I use last time event on client. Will keepLast option solve my issue? My demo says 'yes', test code on server that generates 4 events:

const startMessaging = function GenerateStatus() {
  const arrStatus = [
    'Calling', //Call is coming to operator SoftPhone
    'PickUp', //Operator starts talking
    'CallEnded', //Operator ends talking, HangUp
    'CDR' //Call ends
  ];
  let i = 0;
  let timerId = setInterval(() => {
    console.log(arrStatus[i]);
    i++; i=i % 4;
    app.log.add( 
      { type: 'CHANGE_CALL_STATUS', callStatus: arrStatus[i] },
      { keepLast: 'app/lastCallStatus', users: ['vfink_user']}
    );
  }, 5000);

  setInterval(() => {clearInterval(timerId)}, 20000);
};

and after 4 events do nothing. Then I start client and get only last call status. This is that I needed. Last event didn't disappeared, all previous events were ignored by client. image

Looks good, what's wrong with my logic?

ai commented 6 years ago

But the fastest support, thx!

😸

Looks good, what's wrong with my logic?

Everything is good with logic and code.

You just don't need to have last action in the memory. Your app reacts on last status from the server and doesn't need this status anymore.

So you even not using store, Client remove action from the memory just after this action was processed by app.

( I explain this stuff with reasons just to give you more understanding, you don't need to change the code)