-
-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Suggestion: await new messages #28
Comments
Doesn't the event handler for messages already cover this? |
yes, but it is not promise-based. if you are doing something async and sequential, you have to write a promise wrapper for it. |
Maybe I'm having a hard time imagining your scenario. If you're doing something asynchronous, I'd think you could just make the event handler itself an asynchronous function and use I'm also going off the example you gave. It could be that you're imagining something more complex. |
For example, two parties doing a Diffie-Hellman Key Exchange: Stage 2: while True: |
Ah, I see. Well I think one way to get around that is if you "typed" your messages in some way. Then you could circumvent the For instance, you could have one type of message for Stage 1 and then another type of message for Stage 2. You'd end up with some kind of switch/case/if/else block but it would get the job done. Seeing the while true just reminds me of what (I think) event handlers were made to take care of. |
The best of promise is that it can eliminate those hard-to-read switch-cases. |
I implemented similar requirement this way (not sure if really correct, but it works for me): // promisified onMessage callback
function getResponse(mt) {
return new Promise(((resolve, reject) => {
wsp.onMessage.addListener(message => {
//console.log("<", message);
if(mt == JSON.parse(message).mt) {
wsp.removeAllListeners();
resolve(message);
} else {
wsp.removeAllListeners();
reject();
}
});
}));
}
const openWebSocket = async function (){
await wsp.open();
await wsp.send(JSON.stringify({ mt: "AppChallenge" }));
const challenge = JSON.parse(await getResponse("AppChallengeResult")).challenge;
await wsp.send(JSON.stringify(loginMessage(challenge)));
var resp = await getResponse("AppLoginResult");
await wsp.close();
return JSON.parse(resp).ok;
}
openWebSocket(); |
Yeah I get that. To be fair though, some people may prefer that over infinite loops, especially since they don't always behave as expected when it comes to asynchronous behavior. Conditional blocks can be simple to read if they're structured well (unless you have a million cases...but hopefully you wouldn't). I think there may be another library that works with websockets in such a way that you're adding listeners for custom events. That's also an approach if you're trying to avoid conditional blocks. A promise listener system could potentially be cool. But I think there would be some limitations. I definitely see how the library as it is now enables people to do some things that they wouldn't easily be able to do without it, especially when it comes to testing. But for an infinite loop that awaits messages and responds to them, it feels like it could easily become redundant when compared to the event handling system. Again, that's kind of what it was created for. |
I think what you said makes sense. There can be another library on top of ws to implement that type of workflow. I also think that there might be clashes if we allow both promise-based onmessage and handler-based onmessage. |
Interesting discussion! const messageWithFoo = await wsp.waitUnpackedMessage(data => Boolean(data.foo)); Implementation is similar to @DronNick What do you think? |
This would be useful. I talk to an API that can accept and return different or even missing RequestIDs on the same connection, so the request-response mechanism with one static ID does not work for me here. By the way, great work done on this library, Большое спасибо :) |
I agree with DronNick. The library is super neat! My main concern was that if the solution/implementation turned out to be non-trivial, it could be a lot of work to kind of reinvent the wheel. But if the implementation is easy then I guess it could be useful to have. In general, I think promises have always been preferred over callbacks due to their superior structure. But as I kind of said before, it's hard for me to imagine a promise-based listener getting very far without turning into a loop with switch/case/if/else blocks -- at which point it basically returns to the form of an event handler. For complex websocket interactions that can be expressed as a loop with a single, straightforward responsibility/flow (no conditional blocks), a promise-based listener would probably do well. It could potentially be easier to read at face value, though it would require the developer to do a bit more learning to fully understand. So there are trade-offs |
Thank you, guys! Reopening the issue. |
I totally support the addition of a method like this, I was looking for the exact same thing. |
I'm working on this at present, so I thought I'd add some observations. -- The function from @DronNick basically does this: Is that the only or most general rule we want? I am not sure. In my particular case I need something like: If we take some time on this issue and I explore it further, |
Maybe the target should be "Wait until the matching message come" |
Adding a const messageWithFoo = await wsp.waitUnpackedMessage(data => Boolean(data.foo), { timeout: 1000 }); By default no timeout applied. |
Of course, you are welcome! |
Released as v2.0.1. |
I hope this package can enable us to do the following:
This is actually not that trivial if we need to handle connection error without a wrapper.
The text was updated successfully, but these errors were encountered: