Closed YievCkim closed 1 year ago
It works using decoder::decode_udp
. Is it a feature ? Why not a decode function protocol agnostic ?
Hey @MikHulk !
The naming is a bit misleading, decode_tcp is actually protocol agnostic and just takes a byte slice to decode.
Other than that, I'm not sure at the moment why decode_tcp
fails in the server. Which rosc
version are you using?
I tried to reproduce the issue with your example files, but the server is not compiling:
$ cargo build --bin server
Compiling example v0.1.0 (/private/var/folders/mc/3ssj7_c51dv76d6ll79s5l3w0000gn/T/tmp.pmm1mYUl/example)
error[E0432]: unresolved import `tokio::io::AsyncReadExt`
--> src/server/server.rs:3:5
|
3 | use tokio::io::AsyncReadExt;
| ^^^^^^^^^^^------------
| | |
| | help: a similar name exists in the module: `AsyncRead`
| no `AsyncReadExt` in `io`
error[E0432]: unresolved import `tokio::net::TcpListener`
--> src/server/server.rs:4:5
|
4 | use tokio::net::TcpListener;
| ^^^^^^^^^^^^^^^^^^^^^^^ no `TcpListener` in `net`
|
help: consider importing this struct instead
|
4 | use std::net::TcpListener;
| ~~~~~~~~~~~~~~~~~~~~~
error[E0433]: failed to resolve: could not find `main` in `tokio`
--> src/server/server.rs:6:10
|
6 | #[tokio::main]
| ^^^^ could not find `main` in `tokio`
error[E0425]: cannot find function `spawn` in crate `tokio`
--> src/server/server.rs:17:24
|
17 | tokio::spawn(async move {
| ^^^^^ not found in `tokio`
|
help: consider importing this function
|
1 | use std::thread::spawn;
|
help: if you import `spawn`, refer to it directly
|
17 - tokio::spawn(async move {
17 + spawn(async move {
|
warning: unused imports: `OscMessage`, `OscPacket`
--> src/server/server.rs:2:12
|
2 | use rosc::{OscMessage, OscPacket};
| ^^^^^^^^^^ ^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0752]: `main` function is not allowed to be `async`
--> src/server/server.rs:7:1
|
7 | async fn main() -> Result<(), Box<dyn std::error::Error>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` function is not allowed to be `async`
Some errors have detailed explanations: E0425, E0432, E0433, E0752.
For more information about an error, try `rustc --explain E0425`.
warning: `example` (bin "server") generated 1 warning
error: could not compile `example` due to 5 previous errors; 1 warning emitted
```
Hi @klingtnet
Sorry I should start with that this is my Cargo.toml:
[package]
name = "hello"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio = { version = "1.27.0", features = ["full"] }
rosc="0.10.0"
I looked into decode_tcp tests, ans it seems there is some prefdix added in order to build something onto decode_tcp can work.
I remembered what the problem is, if you decode OSC messages from a TCP stream then the OSC specification expects that the size of the message is the first element in the byte-stream:
In a stream-based protocol such as TCP, the stream should begin with an int32 giving the size of the first packet, followed by the contents of the first packet, followed by the size of the second packet, etc.
That's why decode_tcp
has failed in your server, and why it's actually named decode_tcp
and not just decode
. Of course, the doc string could be a bit more explicit and explain this. I might add a note about this condition to the docs.
this is my rustc version:
mik@debian:~/hello$ cargo --version
cargo 1.69.0 (6e9a83356 2023-04-12)
mik@debian:~/hello$ rustc --version
rustc 1.69.0 (84c898d65 2023-04-16)
mik@debian:~/hello$
What was your setup when you try ?
It's
rustc 1.71.0-nightly (b628260df 2023-04-22
however, it worked with tokio = { version = "1.27.0", features = ["full"] }
.
As explained in my previous message, this is not an issue with rosc
. So I'll close this issue if there's no objection from your side.
I remembered what the problem is, if you decode OSC messages from a TCP stream then the OSC specification expects that the size of the message is the first element in the byte-stream:
In a stream-based protocol such as TCP, the stream should begin with an int32 giving the size of the first packet, followed by the contents of the first packet, followed by the size of the second packet, etc.
That's why
decode_tcp
has failed in your server, and why it's actually nameddecode_tcp
and not justdecode
. Of course, the doc string could be a bit more explicit and explain this. I might add a note about this condition to the docs.
humm ok. But I have a tcp connection here. If I follow the specification I should set this byte. Is there something to encode tcp packet ? I think I can implement that on my side. Just to be sure.
I didn't read extensively OSC specification, I am reading it right now. I am not sure if this byte is something from TCP or OSC.
no problem. I am looking specification.
Is there something to encode tcp packet ?
There's no method that does that for you, but it might be a good idea to add some utility function like encode_tcp
to the API of rosc.
yes I have a local repo. I could do that.
For documentation this is the proper way to send Osc packet with tcp:
use rosc::encoder;
use rosc::{OscMessage, OscPacket, OscType};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "127.0.0.1:9000";
let mut stream = TcpStream::connect(addr).await?;
let osc_packet = OscPacket::Message(OscMessage {
addr: "/greet/me".to_string(),
args: vec![OscType::String("hi!".to_string())],
});
if let Ok(buf) = encoder::encode(&osc_packet) {
println!("send packet");
println!("{:?}", buf);
stream.write_all(&(buf.len() as u32).to_be_bytes()).await?;
stream.write_all(&buf).await?;
println!("transmitted");
}
Ok(())
}
I'll try an implementation this weekend. Thank you !
Hello,
I am trying to use rosc from tokio. My first step is to decode and display incoming osc messages. I have made the server:
and a simple client inspired from documentation:
When the server receives the packet it seems to fail decoding it, and put everything in the left first tuple element:
I have made a little program to see what happens:
got this output:
I guess I missuse the api. I tried to find something to decode directly from a buffer in the API without succeed.