Comments (20)
I think I agree with you, will have a closer look Tomorrow.
from simple-websocket-server.
PS: the send function may also be easier to use with a plant string argument.
from simple-websocket-server.
Sure, could add a send with string argument. Streams should require less copying though, since strings need to resize when adding to them, while streams add the data at separate locations in memory. Might also be that it is possible to do the masking of data from client within the stream instead of adding the result at different stream or string.
If you see on the client, the Message data is never copied, and this is possible because the message from server is not masked here. Main problem would be that the onmessage would be different on server and client, since the client::onmessage should have its Message as stream to avoid copy to string.
from simple-websocket-server.
When I think about the the Message stream could be stringstream I think, that is for both the client and server, and still avoid copy on the client code. Is that satisfactory you think?
from simple-websocket-server.
It seems like it is possible to modify the stream buffer directly and thus avoid a copy to a new stream, and then use stringstream as the Message stream on both client and server. I think this is the best solution, just need to subclass a streambuf class to receive the pointers to the chars in a stream directly.
from simple-websocket-server.
I guess you know best, I had a really quick look at your code. I thought things where strange when I saw that (server_ws.hpp:425)
std::ostream message_data_out_stream(&message->data_buffer);
for(size_t c=0;c<length;c++) {
message_data_out_stream.put(raw_message_data.get()^mask[c%4]);
}
Yes, stringstream would already be a nice improvement.
PS: to prevent string reallocations, one can use std::string::reserve
from simple-websocket-server.
I have looked abit more at this, and the solution seems to be a filtered output stream, that is using stringstream with a custom streambuffer (handling the websocket masking of data from client), maybe using Boost.Iostreams. This way one would avoid copy (for instance if one would only look at the first bytes of a Message), and if you'd want a string using stringstream::str() one would get the data only with one copy, as would be the case if the Message stored the data as string.
from simple-websocket-server.
I looked into code and found it seems not yet support binary data exchange between client and server.
Or just my misunderstanding...
from simple-websocket-server.
See https://github.com/eidheim/Simple-WebSocket-Server/blob/master/server_ws.hpp#L149 and https://github.com/eidheim/Simple-WebSocket-Server/blob/master/client_ws.hpp#L93 (client_ws is actually missing that comment, I'll fix that on Saturday). See also #16 that will be fixed then.
The fourth parameter in SocketServer::send and SocketClient::send, fin_rsv_opcode, tells which kind of message it is, 129 for text and 130 for binary. I'll change the comments to doxygen as well so this shows in IDE's supporting this. Binary/text is mostly for UTF-8 parsing I think, so it only affects clients like web browsers that try to make sense of text messages (which should be UTF-8 compatible if I'm not wrong).
from simple-websocket-server.
Thanks for pointing it out. What I am trying to do to send a photo file from client device to a python based websocket server made by tornado. I am not sure if I need to modify client_ws.hpp to support ifstream. Could you kindly help to show how to do binary data exchange based on this project?
from simple-websocket-server.
Based on ws_examples:
echo.onmessage=[&server](shared_ptr<WsServer::Connection> connection, shared_ptr<WsServer::Message> message) {
auto message_str=message->string();
cout << "Server: Message received: \"" << message_str << "\" from " << (size_t)connection.get() << endl;
cout << "Server: Sending message \"" << message_str << "\" to " << (size_t)connection.get() << endl;
auto send_stream=make_shared<WsServer::SendStream>();
*send_stream << message_str; //instead of message_str, insert raw photo bytes here with for instance send_stream->write
server.send(connection, send_stream, [](const boost::system::error_code& ec){
if(ec) {
cout << "Server: Error sending message. " <<
//See http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference.html, Error Codes for error code meanings
"Error: " << ec << ", error message: " << ec.message() << endl;
}
}, 130);
};
See 130 on one of the last lines, and the comment before server.send.
Edit: I created a server onmessage here, but the client one is very similar.
from simple-websocket-server.
I followed your instructions to send a photo as the following code:
auto send_stream=make_shared<WsClient::SendStream>();
{
std::ifstream infile(JPG_FILE, ios::in | ios::binary);
std::ofstream outfile ("new.jpg",std::ofstream::binary);
// get size of file
infile.seekg (0,infile.end);
long nSize = infile.tellg();
infile.seekg (0);
char* buffer = new char[nSize];
// read content of infile
infile.read (buffer,nSize);
// write to outfile
send_stream->write(buffer, nSize);
outfile.write (buffer, nSize);
// release dynamically-allocated memory
delete[] buffer;
infile.close();
outfile.close();
}
client.send(send_stream, nullptr, 130);
But what I received on server is a garbage, but I verified what I saved in new.jpg is exactly the same as my source photo. Did I make anything wrong?
Edit: made it more readable
from simple-websocket-server.
Try sending a smaller message to the server and see if you can verify the bytes received there. Try both text and binary messages, in case the server does not support binary messages. If it does not support binary, you can send it as text. In this case it will not matter I think.
from simple-websocket-server.
I found the binary size received on websocket server is correct, but content is not. I used to use original ws_example to send "Hello" to tornado server and work well. Tornado websocket server was used to work correctly with javascript websocket client in case of photo upload. So I can only doubt if I probably did something wrong.
from simple-websocket-server.
Try to send the image as text message (129 instead of 130), and see if there is a difference.
from simple-websocket-server.
Also, if you have a link to the python websocket server, I can try this on Saturday and see if I can figure it out.
from simple-websocket-server.
I did several tests regarding to your suggestions as following:
In case of using 129 (text mode) to send, 0 bytes received and decoded from websocket
server, but 130 (binary mode) can get the whole picture size even content is corrupted.
I also tried to send a text file (100 lines ASCII code with \r\n only) using binary mode,
and found websocket server could correctly receive and decode the text file back.
I also noticed, in case of photo upload, the binary data received on server is different
to different send() using same binary data source. I doubt if the random part might be a problem,
and modified https://github.com/eidheim/Simple-WebSocket-Server/blob/master/client_ws.hpp#L101 to mask[c] = 0xff, and verified even though the photo data I received is still incorrect, but the data I decoded from websocket server would be the same as different send() with same binary source.
I also noticed the lastest version of client_ws.hpp was updated to add some static_cast, but after I update client_ws.hpp to latest version, test result is still the same.
Hopefully, my test results could be a little bit help to figure out what wrong it is.
PS: about the tornado websocket server I referring to, please find package and installation guide in http://www.tornadoweb.org/en/stable/
from simple-websocket-server.
I tested the latest client (the changes should not have any effect on this issue, but maybe) on a javax.websocket server using binary messages, and it works on all size variations. However, I had to specify a specific endpoint on the Java server code to handle binary messages, but that was it. Maybe the python server has a similar issue?
Anyway, closing this issue, as its not, at least not now, an issue with Simple-WebSocket-Server.
from simple-websocket-server.
I found what I tested before is the lastest released v1.2, and I donwloaded lastest source and tested again, I confirmed the latest source indeed can send binary data to tornado python websocket server without content corruption. Thanks for your support...
from simple-websocket-server.
Good to hear, when I think about it, the issue was related to #16. That is, sending multiple sends to actually both server and client could interleave and lead to corrupted messages. Thank you for reporting the issue.
from simple-websocket-server.
Related Issues (20)
- [suggest] Send/Broadcast and Text/BinaryMode HOT 1
- Standalone Asio not found - but asio.hpp is present HOT 4
- re again WssClient::start causes on_error HOT 10
- When I use Google Chrome it happend a error. HOT 3
- exception thrown in server start (boost related) HOT 4
- Connection Timeout HOT 2
- Create example on how to stream data to a client HOT 1
- Unable to compile against standalone asio HOT 1
- How to stop the server? HOT 3
- Installed but ws_examples throws an error HOT 1
- Support for the Sec-WebSocket-Protocol field HOT 3
- fatal error C1083: Cannot open include file : 'pthread.h': No such file or directory HOT 1
- Messages split among frames aren't reasembled HOT 25
- Openssl wants void* instead of char* in 0x1000115fL HOT 1
- how to initiate send message from client HOT 3
- Client request error: End of file
- Access violation exeption HOT 3
- gdiplus
- Can't use wss client HOT 5
- Integration with Simple-Web-Server HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from simple-websocket-server.