I have a question.
What time must use .option() and what time must use .childOption()?
I have a server.
I setup server by below lines. it is correct?
.option(ChannelOption.SO_BACKLOG, defaultConnectionBacklog);
.option(ChannelOption.SO_REUSEADDR, true);
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
.childOption(ChannelOption.SO_KEEPALIVE, true);
.childOption(ChannelOption.SO_REUSEADDR, true);
.childOption(ChannelOption.TCP_NODELAY, true);
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
when you start a server:
option is used by XXXServerSocketChannel(e.g. NioServerSocketChannel)
childOption is used by the channel accpted by this ServerChannel
when you start a client:
you can only use option, because there's no child channel exsited.
so in your question,.childOption(ChannelOption.SO_REUSEADDR, true); is useless in the accepted Channel
for more detail, you can read the method channelRead in ServerBootstrapAcceptor class, the code is what to do when a ServerChannel accept a Channel.
P.S. ServerBootstrapAcceptor is the default handler in a ServerChannel pipeline.
Related
I want to get the metrics from vert.x with Hawkular, but I have problem.
Following the tutorial of this. http://vertx.io/docs/vertx-hawkular-metrics/java/
Then, I change the code of the tutorial of vert.x
http://vertx.io/blog/my-first-vert-x-3-application/
like this.
from this
#Before
public void setUp(TestContext context) {
vertx = Vertx.vertx();
vertx.deployVerticle(MyFirstVerticle.class.getName(),
context.asyncAssertSuccess());
}
to this
VertxOptions vertxOptions = new VertxOptions()
.setMetricsOptions(new VertxHawkularOptions()
.setHost("localhost")
.setPort(8080)
.setTenant("com.acme")
.setAuthenticationOptions(
new AuthenticationOptions()
.setEnabled(true)
.setId("jdoe")
.setSecret("password")).setEnabled(true));
vertx = Vertx.vertx(vertxOptions);
JsonObject message = new JsonObject()
.put("id", "myapp.files.opened")
.put("value", 7);
vertx.eventBus().publish("metrics", message);
But I think I there are no changes in Hawkular.
First of all, I checked with WireShark, there looks like no connection of HTTP request of this application.
I want to know if I execute this code, can I see some change in the Hawkular Metrics?
I already checked.
this program pass these codes.
even though I change the Host and Port wrong one, there are no execption.
I think the test process finishes before the metrics had time to get reported. I tried with your example (which looks correct beside this timing issue), and had to put a Thread.sleep of 1 second after publishing on the event bus in order to see something in Hawkular.
curl -u jdoe:password -H "Hawkular-Tenant: com.acme" http://localhost:8080/hawkular/metrics/counters
now gives
[{"id":"vertx.eventbus.publishedRemoteMessages","dataRetention":14,"type":"counter","tenantId":"com.acme"},{"id":"vertx.pool.worker.vert.x-internal-blocking.queuedCount","dataRetention":14,"type":"counter","tenantId":"com.acme"},{"id":"vertx.eventbus.receivedMessages","dataRetention":14,"type":"counter","tenantId":"com.acme"}, etc.
I have a ServiceWorker registered on my page and want to pass some data to it so it can be stored in an IndexedDB and used later for network requests (it's an access token).
Is the correct thing just to use network requests and catch them on the SW side using fetch, or is there something more clever?
Note for future readers wondering similar things to me:
Setting properties on the SW registration object, e.g. setting self.registration.foo to a function within the service worker and doing the following in the page:
navigator.serviceWorker.getRegistration().then(function(reg) { reg.foo; })
Results in TypeError: reg.foo is not a function. I presume this is something to do with the lifecycle of a ServiceWorker meaning you can't modify it and expect those modification to be accessible in the future, so any interface with a SW likely has to be postMessage style, so perhaps just using fetch is the best way to go...?
So it turns out that you can't actually call a method within a SW from your app (due to lifecycle issues), so you have to use a postMessage API to pass serialized JSON messages around (so no passing callbacks etc).
You can send a message to the controlling SW with the following app code:
navigator.serviceWorker.controller.postMessage({'hello': 'world'})
Combined with the following in the SW code:
self.addEventListener('message', function (evt) {
console.log('postMessage received', evt.data);
})
Which results in the following in my SW's console:
postMessage received Object {hello: "world"}
So by passing in a message (JS object) which indicates the function and arguments I want to call my event listener can receive it and call the right function in the SW. To return a result to the app code you will need to also pass a port of a MessageChannel in to the SW and then respond via postMessage, for example in the app you'd create and send over a MessageChannel with the data:
var messageChannel = new MessageChannel();
messageChannel.port1.onmessage = function(event) {
console.log(event.data);
};
// This sends the message data as well as transferring messageChannel.port2 to the service worker.
// The service worker can then use the transferred port to reply via postMessage(), which
// will in turn trigger the onmessage handler on messageChannel.port1.
// See https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
navigator.serviceWorker.controller.postMessage(message, [messageChannel.port2]);
and then you can respond via it in your Service Worker within the message handler:
evt.ports[0].postMessage({'hello': 'world'});
To pass data to your service worker, the above mentioned is a good way. But in case, if someone is still having a hard time implementing that, there is an other hack around for that,
1 - append your data to get parameter while you load service-worker (for eg., from sw.js -> sw.js?a=x&b=y&c=z)
2- Now in service worker, fetch those data using self.self.location.search.
Note, this will be beneficial only if the data you pass do not change for a particular client very often, other wise it will keep changing the loading url of service worker for that particular client and every time the client reloads or revisits, new service worker is installed.
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'm a noob to Sockets Programming.Maybe am asking a fundamental question. Please bear with me.
I wrote a sample netty server and started it from console. It runs fine. The problem i have is that when i run the same server from two console windows, i'd expect one of them to throw 'Address already in use' exception. It does not do that and I dont understand why. Please help.
public static void main(String[] args) {
ChannelFactory cf = new NioServerSocketChannelFactory(Executors.newFixedThreadPool(100), new MemoryAwareThreadPoolExecutor(1000,2048,25096,2,TimeUnit.SECONDS));
//ChannelFactory cf = new OioServerSocketChannelFactory(Executors.newFixedThreadPool(100), Executors.newCachedThreadPool());
ServerBootstrap bootstrap = new ServerBootstrap(cf);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
#Override
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new ChannelHandler("test"));
}
});
bootstrap.setOption("child.keepAlive", true);
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.reuseAddress", true);
bootstrap.setOption("child.connectTimeoutMillis", 30000);
//NEVER bootstrap.setOption("child.readWriteFair", true);
//bootstrap.setOption("disconnect", true);
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("reuseAddress", true);
bootstrap.setOption("connectTimeoutMillis", 30000);
bootstrap.setOption("readWriteFair", true);
bootstrap.bind(new InetSocketAddress(9998));
}
To sum up the many comments above:
The bootstrap.setOption("reuseAddress", true); option will allow binding to an already bound ip:port combination. This is usually used to be able to restart a server if it crashed/got killed (so while the socket is still in the TIME_WAIT state).
In Windows it is possible to have two completely different programs bind the exact same ip:port. So even if in your app you have bootstrap.setOption("reuseAddress", false); it is still possible for another app (i.e. malicious) that enables SO_REUSEADDR to succesfully bind on your ip:port.
See here for more details: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx
I have a C# service that runs continuously with user credentials (i.e not as localsystem - I can't change this though I want to). For the most part the service seems to run ok, but ever so often it bombs out and restarts for no apparent reason (servicer manager is set to restart service on crash).
I am doing substantial event logging, and I have a layered approach to Exception handling that I believe makes at least some sort of sense:
Essentially I got the top level generic exception, null exception and startup exception handlers.
Then I got various handlers at the "command level" (i.e specific actions that the service runs)
Finally I handle a few exceptions handled at the class level
I have been looking at whether any resources aren't properly released, and I am starting to suspect my mailing code (send email). I noticed that I was not calling Dispose for the MailMessage object, and I have now rewritten the SendMail code as illustrated below.
The basic question is:
will this code properly release all resources used to send mails?
I don't see a way to dispose of the SmtpClient object?
(for the record: I am not using object initializer to make the sample easier to read)
private static void SendMail(string subject, string html)
{
try
{
using ( var m = new MailMessage() )
{
m.From = new MailAddress("service#company.com");
m.To.Add("user#company.com");
m.Priority = MailPriority.Normal;
m.IsBodyHtml = true;
m.Subject = subject;
m.Body = html;
var smtp = new SmtpClient("mailhost");
smtp.Send(m);
}
}
catch (Exception ex)
{
throw new MyMailException("Mail error.", ex);
}
}
I know this question is pre .Net 4 but version 4 now supports a Dispose method that properly sends a quit to the smpt server. See the msdn reference and a newer stackoverflow question.
There are documented issues with the SmtpClient class. I recommend buying a third party control since they aren't too expensive. Chilkat makes a decent one.