-
-
Notifications
You must be signed in to change notification settings - Fork 343
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
WebSocket support (#83) #1214
base: main
Are you sure you want to change the base?
WebSocket support (#83) #1214
Conversation
295d52c
to
4b17f43
Compare
4b17f43
to
76f077d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this huge amount of work!
I started testing and reviewing but encountered some errors that prevented me from continuing further. I will retest as you update the PR.
Aside from the comments I already put on the code, here are some remarks:
- I think the badge should be reused in the routes menu with a "WS" instead of an icon. Same for the logs menu:
-
in conversation mode, when I was modifying the body, latency, rules, etc. It wasn't applied until I restarted the server. This is not the case with the regular HTTP or CRUD routes. I don't know what is missing in the code, but you will see for the HTTP/CRUD routes a
refreshEnvironment
function being called before each request (this.refreshEnvironment(); -
I'm not sure if the fallback mode make sense for a persisting websocket connection. I think this option should be disabled.
- I think the initial naming of the responses could be kept: "Response 1 {documentation}"
-
I didn't see the WS_UNKNOWN_ROUTE happening in the logs when trying to connect on the wrong route
-
when activating one of the streaming options (broadcast or one-to-one) I always got the same error message:
{"date":"Tue Jan 16 2024 10:58:16 GMT+0100 (Central European Standard Time)","error":{},"exception":true,"level":"error","message":"uncaughtException: Unexpected end of JSON input\nSyntaxError: Unexpected end of JSON input\n at JSON.parse (<anonymous>)\n at parseWebSocketMessage (c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\templating-helpers\\web-socket-helpers.js:25:25)\n at WebSocketHelpers (c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\templating-helpers\\web-socket-helpers.js:38:55)\n at TemplateParser (c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\template-parser.js:29:103)\n at MockoonServer.deriveFinalResponseContentForWebSockets (c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\server\\server.js:488:60)\n at Timeout._onTimeout (c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\server\\server.js:511:34)\n at listOnTimeout (node:internal/timers:569:17)\n at process.processTimers (node:internal/timers:512:7)","os":{"loadavg":[0,0,0],"uptime":98385.875},"process":{"argv":["c:\\dev\\mockoon\\mockoon\\packages\\desktop\\node_modules\\electron\\dist\\electron.exe",".","--remote-debugging-port=8888","--data-folder=./tmp"],"cwd":"c:\\dev\\mockoon\\mockoon\\packages\\desktop","execPath":"c:\\dev\\mockoon\\mockoon\\packages\\desktop\\node_modules\\electron\\dist\\electron.exe","gid":null,"memoryUsage":{"arrayBuffers":0,"external":3718739,"heapTotal":54034432,"heapUsed":46952552,"rss":155590656},"pid":40784,"uid":null,"version":"v18.16.1"},"stack":"SyntaxError: Unexpected end of JSON input\n at JSON.parse (<anonymous>)\n at parseWebSocketMessage (c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\templating-helpers\\web-socket-helpers.js:25:25)\n at WebSocketHelpers (c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\templating-helpers\\web-socket-helpers.js:38:55)\n at TemplateParser (c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\template-parser.js:29:103)\n at MockoonServer.deriveFinalResponseContentForWebSockets (c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\server\\server.js:488:60)\n at Timeout._onTimeout (c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\server\\server.js:511:34)\n at listOnTimeout (node:internal/timers:569:17)\n at process.processTimers (node:internal/timers:512:7)","timestamp":"2024-01-16T09:58:16.377Z","trace":[{"column":null,"file":null,"function":"JSON.parse","line":null,"method":"parse","native":false},{"column":25,"file":"c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\templating-helpers\\web-socket-helpers.js","function":"parseWebSocketMessage","line":25,"method":null,"native":false},{"column":55,"file":"c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\templating-helpers\\web-socket-helpers.js","function":"WebSocketHelpers","line":38,"method":null,"native":false},{"column":103,"file":"c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\template-parser.js","function":"TemplateParser","line":29,"method":null,"native":false},{"column":60,"file":"c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\server\\server.js","function":"MockoonServer.deriveFinalResponseContentForWebSockets","line":488,"method":"deriveFinalResponseContentForWebSockets","native":false},{"column":34,"file":"c:\\dev\\mockoon\\mockoon\\packages\\commons-server\\dist\\cjs\\libs\\server\\server.js","function":"Timeout._onTimeout","line":511,"method":"_onTimeout","native":false},{"column":17,"file":"node:internal/timers","function":"listOnTimeout","line":569,"method":null,"native":false},{"column":7,"file":"node:internal/timers","function":"process.processTimers","line":512,"method":"processTimers","native":false}]}
Some questions, as I couldn't test everything:
- in streaming mode, does the rules, random/sequential/disable rules modes work?
- Shouldn't we put a minimum interval for the streaming mode? I'm afraid if we can setup something really small like 1ms it could crash everything.
- I think the streaming one-to-one icon could be another one, a bit clearer: maybe this one? We already have it in the app but don't use it anymore.
Thank you. Let me know on Discord if you want to discuss some of these questions.
packages/commons-server/src/libs/templating-helpers/web-socket-helpers.ts
Outdated
Show resolved
Hide resolved
packages/commons-server/src/libs/ws-response-rules-interpreter.ts
Outdated
Show resolved
Hide resolved
packages/desktop/src/renderer/app/components/menus/routes-menu/routes-menu.component.html
Outdated
Show resolved
Hide resolved
c3836fc
to
ea77b33
Compare
ea77b33
to
7e1466a
Compare
To answer your questions. 1. In streaming mode, does the rules, random/sequential/disable rules modes work? 2. Shouldn't we put a minimum interval for the streaming mode? I'm afraid if we can setup something really small like 1ms it could crash everything. 3. I think the streaming one-to-one icon could be another one, a bit clearer: maybe this one? We already have it in the app but don't use it anymore. |
7e1466a
to
2aac6e3
Compare
7c37dbc
to
8482905
Compare
e66061d
to
a6ef8c8
Compare
a6ef8c8
to
02435f2
Compare
482c5d4
to
7c7c35d
Compare
Hi! What's needed to get this completed, @255kb and @isuru89 ? I'm working for a company that is heavily using the forked version so far (with great success!), and would love to see this come to fruition, and make developing for and with websockets easier. It's already easier as it is now, so we're very thankful for such a contribution to such a wonderful tool! 😄 I'm not a JS dev, and have never touched electron, but I'm more than willing to test on Windows and Linux, and could provide feedback on that matter. I could look at the code as well, but I fear my lack of experience in JS and its inevitable quirks will be a greater hindrance than a help. 😅 |
Hi @inuitviking Again, not talking about broadcasting mode that sends the same message all the time. I think it makes sense. @isuru89 I don't think you had time to change this and update your PR? As a side note, as this PR is modifying the data model (new route type and options) and because we now have a cloud, and because we don't force updates (on purpose), this must be released in a major version. |
Thanks for the swift reply!
That explains the odd behaviour with the websocket when testing, and it working as expected with only the first few messages after a restart of the server. Would be cool with a resolution on that matter! 😄
Completely understandable! Gotta be careful. I'll be using the fork for now, and if I find the time to look into the code, I'll hop back in here if it's needed. :) |
If you can test more deeply and provide some feedback, that would be really appreciated! |
7c7c35d
to
40eb7e6
Compare
40eb7e6
to
8e48969
Compare
@255kb |
Thank you. |
ws2.close(); | ||
}); | ||
|
||
it('should return correct response for each message', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@255kb
Isn't this a test case fulfilling what you mean by the other thread? Or, do you have any other different scenario?
Technical implementation details
After a completion of successful PoC, I thought I would raise this pull request with the initial implementation of the WebSockets.
This implementation covers all basic features of a websocket. Followings are the features and limitations.
Features:
ws://localhost:3000/<sub-path>
)Limitations:
ws/wss
portocols.Screenshots:
Adding a WebSocket route.
View of the WebSocket route.
Shows it in logs.
Checklist
CLI automated tests added (@mockoon/cli)Closes #83