Skip to content
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

feat: emit multipe parameters #249

Closed
wants to merge 6 commits into from
Closed

feat: emit multipe parameters #249

wants to merge 6 commits into from

Conversation

SSebo
Copy link
Contributor

@SSebo SSebo commented Oct 24, 2022

js client can emit multiple parameters in one call. user socketio server socket.on("foo", async (userId, body, callback)=>{}) (#246) accept this kind of data which rust-socektio can not emit.

@codecov
Copy link

codecov bot commented Oct 24, 2022

Codecov Report

Merging #249 (12b0d73) into main (4ac27c7) will increase coverage by 0.05%.
The diff coverage is 81.33%.

@@            Coverage Diff             @@
##             main     #249      +/-   ##
==========================================
+ Coverage   86.27%   86.33%   +0.05%     
==========================================
  Files          31       31              
  Lines        2478     2562      +84     
==========================================
+ Hits         2138     2212      +74     
- Misses        340      350      +10     
Impacted Files Coverage Δ
socketio/src/client/builder.rs 92.95% <ø> (ø)
socketio/src/client/client.rs 94.91% <ø> (ø)
socketio/src/lib.rs 100.00% <ø> (ø)
socketio/src/payload.rs 68.29% <51.85%> (-31.71%) ⬇️
socketio/src/client/raw_client.rs 78.50% <62.50%> (+0.87%) ⬆️
socketio/src/socket.rs 87.50% <94.84%> (+9.00%) ⬆️
socketio/src/packet.rs 91.84% <100.00%> (+0.40%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@SSebo SSebo force-pushed the emit_multi branch 2 times, most recently from 0987cdf to fdd47fd Compare October 24, 2022 12:12
Copy link
Collaborator

@ctrlaltf24 ctrlaltf24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Don't quite understand what the problem was, nor the solution, a brief explanation (preferably in comments) as to what happened may be helpful

socketio/examples/callback.rs Outdated Show resolved Hide resolved
socketio/src/client/raw_client.rs Outdated Show resolved Hide resolved
socketio/src/socket.rs Outdated Show resolved Hide resolved
socketio/src/packet.rs Outdated Show resolved Hide resolved
socketio/examples/readme.rs Outdated Show resolved Hide resolved
@david-sailplan
Copy link

I had left an earlier comment but deleted it. Turns out it was an issue on the server side

@david-sailplan
Copy link

This does seem to solve the problem I was experiencing here. Good job

@1c3t3a
Copy link
Owner

1c3t3a commented Oct 25, 2022

First of all thanks for the quick solution @SSebo! But I wanted to ask whether this can be solved by reverting the behaviour of #220. This was the initial reason why I only accepted valid json and nothing else. I would prefer this approach over a completely new API call!

@SSebo
Copy link
Contributor Author

SSebo commented Oct 25, 2022

First of all thanks for the quick solution @SSebo! But I wanted to ask whether this can be solved by reverting the behaviour of #220. This was the initial reason why I only accepted valid json and nothing else. I would prefer this approach over a completely new API call!

The root reason is socketio encoding accept [event, payload1, payload2 ... payloadn] format, original rust_socketio implementation only support [event, only_1_json_payload].
what user want is multiple payloads, and type can be number, string, json, and binary.
only one json payload [event, only_1_json_payload] can not be accepted by server code like socket.on("foo", async (userId, body, callback)=>{})

revert #220 is ok, but we still need a way to emit simple payload like number and string if nodejs socketio server needs.

the new API is a POC, even the name of that API is not good.

@1c3t3a
Copy link
Owner

1c3t3a commented Oct 25, 2022

This is not entirely true, we don't need number since this is part of Json, eg: { "my_number": 1}. Can you confirm that a revert of #220 results in being able to emit to a socketio server with socket.on("foo", async (userId, body, callback)=>{})where body is not empty? :)

@SSebo
Copy link
Contributor Author

SSebo commented Oct 25, 2022

I agree, not include number. #220 is a little wired that callback payload can not emit back, maybe Payload::Json and Payload::Binary are better.

@SSebo
Copy link
Contributor Author

SSebo commented Oct 25, 2022

This is not entirely true, we don't need number since this is part of Json, eg: { "my_number": 1}. Can you confirm that a revert of #220 results in being able to emit to a socketio server with socket.on("foo", async (userId, body, callback)=>{})where body is not empty? :)

@david-sailplan can you confirm that use a single json payload is able to emit to a socketio server with socket.on("foo", async (userId, body, callback)=>{})where body is not empty? :)

@david-sailplan
Copy link

@SSebo I'm not entirely sure what you're asking here. If you're asking if something to the effect of

let payload = json!(("user_id_1", json!({'data": 1})))
socket.emit_with_ack("foo",payload, duration, callback) 

works with server code

socket.on("foo", async (userId, body, callback)=>{
    console.log({userId, body, callback});
    callback(1);
})

I can confirm that it does not. Log would be

{
    userId: ['user_id)1', {'data': 1}]
    body: [Function (anonymous)],
    callback: undefined
}

@david-sailplan
Copy link

If what you're asking is if

let payload = vec![json!(1), json({"data": 2}))]
socket.emit_multi_with_ack("foo", payload, duration, callback)

works with the above server code the answer is yes. It behaves as we expected even after removing the Payload::Number

Copy link
Collaborator

@ctrlaltf24 ctrlaltf24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just dropping by, as always @1c3t3a 's in charge

socketio/src/socket.rs Outdated Show resolved Hide resolved
socketio/src/socket.rs Outdated Show resolved Hide resolved
socketio/src/client/client.rs Outdated Show resolved Hide resolved
@SSebo SSebo changed the title feat: emit multipe payload feat: emit multipe parameters Oct 26, 2022
@SSebo SSebo force-pushed the emit_multi branch 3 times, most recently from 263fd9b to 34275ff Compare October 26, 2022 11:23
Copy link
Collaborator

@ctrlaltf24 ctrlaltf24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for being receptive to comments so far, feel free to ignore the "nit"s you don't want to do, just saying things I noticed.

Changes to Packet's public interface require @1c3t3a 's approval. We MIGHT be able to still squeeze by with changes to Packet, as it's not likely many use it. Your call.

socketio/src/payload.rs Show resolved Hide resolved
payload: Payload,
event: Event,
nsp: &'a str,
event: Option<Event>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: when is event none? Only usage I can see is in the tests

Copy link
Contributor Author

@SSebo SSebo Oct 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found client.emit(Buffer.from([4, 5, 6])); in socket-io.js, I thought event is optional that time. But I lookup the socketio dos, event is not optional. Does this mean the event can be a valid payload?
I could not figure out how to emit like that in rust-socketio.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right now in rust-socketio if only receive 1 item in packet.data, it will be treat as payload, not event.

fn handle_event(&self, packet: &Packet) -> Result<()> {
// unwrap the potential data
if let Some(data) = &packet.data {
// the string must be a valid json array with the event at index 0 and the
// payload at index 1. if no event is specified, the message callback is used
if let Ok(serde_json::Value::Array(contents)) =
serde_json::from_str::<serde_json::Value>(data)
{
let event: Event = if contents.len() > 1 {
contents
.get(0)
.map(|value| match value {
serde_json::Value::String(ev) => ev,
_ => "message",
})
.unwrap_or("message")
.into()
} else {
Event::Message
};
self.callback(
&event,
contents
.get(1)
.unwrap_or_else(|| contents.get(0).unwrap())
.to_string(),
)?;
}
}
Ok(())

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did you find that? Specification only mentions, that when no event is specified, "Message" should be used. So having an Option<Event> would not make sense in that case.

Copy link
Contributor Author

@SSebo SSebo Oct 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@1c3t3a I found it here

client.emit(Buffer.from([4, 5, 6]));

I agree event should not be optional. I just don't know how to emit like js in rust-socketio.
Does that mean this Buffer is event?

socketio/src/socket.rs Show resolved Hide resolved
socketio/src/packet.rs Outdated Show resolved Hide resolved
packet.data = match json_data {
Value::Array(vec) if vec.is_empty() => None,
// Value::Array(vec) if vec.len() == 1 => vec.get(0).map(|v| v.to_owned()),
_ => Some(json_data),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: would this still have the _placeholder in it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, _placeholder will be replaced to real Payload::Binary in socket.rs

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

packet.rs should handle all de-serialization of the packet. This will become more important if/when we want to support multiple versions.

Copy link
Contributor Author

@SSebo SSebo Oct 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BinaryEvent can be mixed with normal data and binary data like client.emit('test', Buffer.from([1, 2, 3]), "4", Buffer.from([5, 6]));, so we can not just remove all _placeholder as we do not know where the binary data is in the sequence of received items. socket.rs will not parse the packet, just to replace _placehoulder to Payload::Binary

I checked socket.io protocol, for now BinaryEvent is not changed when added in version 2. If we do not want to touch _placehoulder in socket.rs, we should replaced to Payload::Binary in packet.rs to keep order of mixed multi payloads. packet.data can not be Vec<Value> or Vec<String> but Vec<Payload>.

socketio/src/client/raw_client.rs Outdated Show resolved Hide resolved
socketio/src/client/raw_client.rs Outdated Show resolved Hide resolved
socketio/src/client/raw_client.rs Show resolved Hide resolved
socketio/src/client/raw_client.rs Outdated Show resolved Hide resolved
Comment on lines +388 to +391
.map(|value| match value {
serde_json::Value::String(ev) => ev,
_ => "message",
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.map(|value| match value {
serde_json::Value::String(ev) => ev,
_ => "message",
})
.and_then(|value| match value {
serde_json::Value::String(ev) => Some(ev),
_ => None
})

@@ -158,6 +158,47 @@ impl Socket {
attachments.push(bin_data);
}

pub(crate) fn decode_binary_payload(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: why did this move? It's only used in raw_client

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found encode is in socket.rs, so I move decode in socket.rs too.

@SSebo SSebo closed this Nov 27, 2022
@ctrlaltf24
Copy link
Collaborator

Why was this closed @SSebo ?

@1c3t3a
Copy link
Owner

1c3t3a commented Jan 15, 2023

Good question!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants