I'm attempting to send a file to the response and support encoding. The code is mostly copied from one of the examples in the Netty github.
ChannelFuture flushFuture;
if (context.pipeline().get(SslHandler.class) == null) {
// SSL not enabled - can use zero-copy file transfer.
context.write(new DefaultFileRegion(raf.getChannel(), 0, getLength()), context.newProgressivePromise());
flushFuture = context.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
} else {
// SSL enabled - cannot use zero-copy file transfer.
try {
// HttpChunkedInput will write the end marker (LastHttpContent) for us.
flushFuture = context.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, getLength(), 8192)),
context.newProgressivePromise());
} catch (IOException e) {
throw new CustomizableResponseTypeException("Could not read file", e);
}
}
When the server is using SSL, all works well. When SSL is not being used, the zero-copy file transfer is being done and the encoding doesn't produce the correct output.
I've ready this blog post that seems to indicate what I'm trying to do could work, however I don't understand what part of the example code could cause it to work. Any tips or help will be appreciated.
Thanks!
It appears it's not possible. The solution is to only use zero-copy for files that are small or not compressible.
Related
I have a section (DropTarget) where the user can drop several items from within my application.
This works fine.
Now I would also like to allow the user to drag files to that DropTarget.
The drop listener that I registered gets notified when I drag a file to the DropTarget, but - as far as I see - does not offer any possibility to consume the dragged file.
Anybody knows how to get this running?
Using Vaadin flow 22.0.7
When you create an Upload component, you can specify a Receiver. You can pass one as a constructor parameter or via upload.setReceiver(Receiver). There are different types of Receivers depending on your use case; you can use a MemoryBuffer if you are ok with putting all of the data in your server memory, but there are other options, like FileBuffer, as can be seen here: https://vaadin.com/docs/latest/ds/components/upload/#handling-uploaded-files-java-only ; you can implement your own Receiver as well.
The Receiver gives you access to the actual streaming content of the file. Typically, you want to access the data in some stage of the upload process, which you can do through different upload listeners. If you just want to deal with it once the upload is fully complete, you can use a SucceededListener:
MemoryBuffer memoryBuffer = new MemoryBuffer();
Upload upload = new Upload(memoryBuffer);
upload.addSucceededListener(event -> {
InputStream fileData = memoryBuffer.getInputStream();
String fileName = event.getFileName();
File targetFile = new File("C:/tmp/" + fileName );
OutputStream outStream = null;
try {
outStream = new FileOutputStream(targetFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
outStream.write(fileData.readAllBytes());
} catch (IOException e) {
e.printStackTrace();
}
});
Implementing your own Receiver gives you more flexibility on how you want to handle the OutputStream from the upload, and of course you might not want to save the upload as a physical file, but put it directly in a database for example.
I am trying to create a communication interface between a python socket server and a Metatrader 5 Expert Advisor.
I've tried multiple approaches and tutorial's I found online for both sockets and websockets. All of these approaches yield the same problem.
Whenever I start a debug on live/historical data, I get a Socket creation error with code 4014. According to the error codes it is a "Function is not allowed for call" error.
Multiple sources recommended to allow web request from specified URL's. Ive done this as well for 127.0.0.1 and localhost. (Tools > options > Expert Advisors)
Why am I getting a function not allowed for call error, and how can this be fixed?
Expert code:
int socket=SocketCreate();
int OnInit()
{
if(SocketConnect(socket,"127.0.0.1",9090,1000))
{
Print("Connected to "," 127.0.0.1",":",9090);
}
else
{
Print(GetLastError());
}
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
SocketClose(socket);
}
void OnTick()
{
SocketClose(socket);
}
We had similar issue in the past and was resolved it by adding the hostname/IP to connect to to the list of allowed URLs in Tools->Options->Expert Advisor.
You can also use a MetaApi service to communicate with MetaTrader via developer-friendly SDKs and code your expert advisor in Javascript, Java or Python.
Hope this is useful to some degree.
I faced the same problem.
Works for me: to point exactly '127.0.0.1' (without upper commas) in address input field.
Also, check your firewall settings - it may block your ports.
The best regards.
I Implemented a HttpListener to process SoapRequests. This works fine but I can't find a soloution for the problem, that some soap-requests take too much time, resulting in timeouts on client side.
How do I let the requesting client know, that his request is not a timeout?
I thought about sending "dummy"-information while the request gets processsed, but the HttpListener only seems to send the data when you Close the response-object, and this can be done only once, so this is not the right thing to do I suppose.
Soloution:
Thread alliveWorker = new Thread(() =>
{
try
{
while (context.Response.OutputStream.CanWrite)
{
context.Response.OutputStream.WriteByte((byte) ' ');
context.Response.OutputStream.Flush();
Thread.Sleep(5000);
}
}
finally
{
}
});
alliveWorker.Start();
doWork();
alliveWorker.Interrupt();
createTheRealResponse();
Sending dummy information is not a bad idea.
I think you need to call the Flush() method on the HttpListenerResponse's OutputStream property after writing the dummy data. You must also enable SendChunked property:
Try sending a dummy space at regular interval:
response.SendChunked = true;
response.OutputStream.WriteByte((byte)' ');
response.OutputStream.Flush();
I see two options - increase timeouts on client side or extend protocol with operation status requests from client for long running operations.
If you are using .net 4.5, take a look at the HttpListenerTimeoutManager Class, you can use this class as a base to implement custom timeout behaviour.
I am having problems deserializing data from a network stream. Once the socket is opened the first read statement is successful but a subsequent attempt to deserialize the data blocks without an error (although it will eventually timeout).
I have checked that the correct data is being sent and that it is correctly formed. To confirm this I tried the same code and same data but using a file stream. I don't get the same behavior - the deserialization step does not block.
I realize that file streams and network streams have some differences but I would have expected the behavior to be the same.
TcpClient client = new TcpClient();
client.Connect(Server, Port);
NetworkStream stream = client.GetStream();
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
XmlReader reader = XmlReader.Create(stream, settings);
MyData recievedData;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyData ));
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && xmlReader.Name == "MyRoot")
{
// The following statement blocks
recievedData= (MyData)xmlSerializer.Deserialize(reader);
}
}
After some additional testing I noted that the deserialization step will resume correctly if I force the server to resend the same message. However the subseqent read statement will also work (picking up the duplicate message) and then block again on the deserialization step.
It might also be worth mentioning the message is a single element. Something like the following:
<MyRoot xmlns="http://www.mydomain.com/mydata" someattribute="123" />
In my app I doing something very similar to what is done in the WiTap project. I use Bonjour to discover peers and then send data over the socket to perform an initial handshake.
I'm able to see the data being sent OTA using Cocoa Packet Analyzer. But the stream: handleEvent: function is never called on the receiving peer side.
What I am able to see is:
Sometimes, when the peer that sent the data exits, the receiver peer seems to get the data.
Sometimes I am able to see an NSStreamEventErrorOccurred error in the handler function.
I'm unable to see any noticeable pattern on when the above behavior occurs.
Here is a bit of the code that might be helpful.
PacketSender and PacketReceiver objects are singletons.
I have verified multiple times that the correct (and the only) instance of these objects are set as delegates while debugging:
if (![netService getInputStream:&_inStream outputStream:&_outStream])
{
[Utilities showAlert:#"Failed connecting to server"];
return BM_ERROR_NETSERVICE_STREAM_FAIL;
}
if(!sharedProtocolManager.mPacketSender)
{
sharedProtocolManager.mPacketSender = [PacketSender sharedSender];
}
if(!sharedProtocolManager.mPacketReceiver)
{
sharedProtocolManager.mPacketReceiver = [PacketReceiver sharedReceiver];
}
if(!sharedProtocolManager.mPacketSender || !sharedProtocolManager.mPacketReceiver)
{
return BM_ERROR_FAIL;
}
[PacketReceiver setupInStream:_inStream];
[PacketSender setupOutStream:_outStream];
}
Inside the PacketReceiver setupInStream: function I have:
if (sharedPacketReceiver->mInStream != inStream)
{
[sharedPacketReceiver->mInStream release];
sharedPacketReceiver->mInStream = [inStream retain];
}
sharedPacketReceiver->mInStream.delegate = sharedPacketReceiver;
Any answers or even suggestions on ways to debug this further would be greatly appreciated.
Thanks!