I am trying to connect to the Pusher service from a .NET application and connecting to the Pusher service is never successful. I have followed step by step how to connect to the service, but nothing happens.
Code:
Pusher pusher = new Pusher("APP KEY", new PusherOptions
{
Encrypted = true,
Cluster = "us2"
});
pusher.Connected += Pusher_Connected;
pusher.ConnectionStateChanged += Pusher_ConnectionStateChanged;
pusher.Error += Pusher_Error;
var state = await pusher.ConnectAsync();
Console.WriteLine($"Current state: {state}");
Console.WriteLine(pusher.Channels.Count);
Console.ReadKey();
NOTES: Obviously I change the APP_KEY for my secret key
The library I use is this: https://github.com/pusher/pusher-http-dotnet
I already managed to connect, the problem was that if I used the "await" to wait to connect or subscribe to a channel, nothing ever happened, but if I did it synchronously, it was possible to connect.
Related
We have a .NET framework 4.5.2 service running that connects to a WebSphere MQ Server (v7.5.0.9). Our service needs to connect to a Queue and put a message. It doesn’t need to receive anything after putting the message. We have this set up in a Test and Production environment. We've had this running for a while without any issues. Now we are facing an error only in the Production environments. The same code works fine in the Test environment. But Production is showing very inconstant results and we are unable to recreate the issue anywhere else.
The only way we are currently able to get it working is by restarting the .NET service multiple times until the service is able to connect to all Queue Managers. Every time we restart the service we get a different result. We may start the service and it would not be able to connect to any of the Queue Managers and then we restart again and 2 of the Queue Managers are able to connect. Once the connection has been made it is stable, the service will be able to put messages in any of the Queues without it ever disconnecting.
Some of the things we have tried
Before this issue, we were using the SYSTEM.DEF.SVRCONN channel to connect to the Queue Managers but we have changed that to use a "Server Connection" channel we have created in each Queue Manager. We can see the new channels are in an Active state but only if it is able to make the initial connection.
Originally we were connecting to a Queue Manager, putting a message, and closing the Queue but we were leaving the Queue Manager open. We have tried to Close and Disconnect the Queue Managers after every message but that seemed to make things worse.
The .Net service and Websphere are on the same box but we have tried disabling the windows firewall on the server in case there was something blocking it. That didn’t seem to make a difference either.
My background is in .NET so I'm not very familiar with the WebSphere UI and even less with the CLI. Any ideas on places to look or commands to run to get any insight on what is going on would be helpful.
The only error we get in WebSphere is "CompCode: 2, Reason: 2009" but in the service we are catching the exception, it says "Error Message: MQRC_CONNECTION_BROKEN"
Below is the code used to connect and send a message. We are using the amqmdnet.dll
try
{
properties = new Hashtable();
properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
properties.Add(MQC.HOST_NAME_PROPERTY, hostName);
properties.Add(MQC.PORT_PROPERTY, port);
properties.Add(MQC.CHANNEL_PROPERTY, channelName);
if (!QueueManagers.ContainsKey(queueManagerName))
{
queueManager = new MQQueueManager(queueManagerName, properties);
QueueManagers[queueManagerName] = queueManager;
}
else
{
queueManager = QueueManagers[queueManagerName];
if (!queueManager.IsConnected)
{
queueManager = new MQQueueManager(queueManagerName, properties);
QueueManagers[queueManagerName] = queueManager;
}
}
queue = queueManager.AccessQueue(queueName, MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING);
message = new MQMessage();
message.ClearMessage();
message.Format = MQC.MQFMT_STRING;
message.Encoding = MQC.MQENC_NATIVE;
message.CorrelationId = MQC.MQCI_NONE;
message.CharacterSet = MQC.MQCCSI_Q_MGR;
message.WriteString(messageString);
queue.Put(message);
}
catch (Exception ex)
{
sentToMQServer = false;
QueueManagers.TryRemove(queueManagerName, out var mgr);
queueManager?.Close();
queueManager?.Disconnect();
if (retry)
SendToMQServer(remoteClient, Message, false);
}
finally
{
message = null;
//QueueManagers.TryRemove(queueManagerName, out var mgr);
if (properties != null)
{
properties.Clear();
properties = null;
}
if (queue != null)
{
queue.Close();
queue = null;
}
//queueManager.Close();
//queueManager.Disconnect();
}
My .NET code can connect and put a message to a remote queue successfuly. However, the same code does not work with local queue. It throws 2085 error. What different setting should be set in code to make that work with local queue?
Here is my code:
Hashtable queueProperties = new Hashtable();
queueProperties[MQC.HOST_NAME_PROPERTY] = "10.x.x.x";
queueProperties[MQC.PORT_PROPERTY] = 1451;
queueProperties[MQC.CHANNEL_PROPERTY] = "TST1.TRADE.CHANNEL";
try
{
// Attempt the connection
queueManager = new MQQueueManager("MYQUEUEMANAGER", queueProperties);
strReturn = "Connected Successfully";
}
catch (MQException mexc)
{
// TODO: Setup other exception handling
throw new Exception(mexc.Message
+ " ReasonCode: " + mexc.ReasonCode
+ "\n" + GetReason(mexc.ReasonCode), mexc);
}
Here, the code is internally using the IIS user id (application pool user) to connect with MQ because this code is run as part of WCF service.
If you run the mqrc utility you can find out what the error code translates to:
$mqrc 2085
2085 0x00000825 MQRC_UNKNOWN_OBJECT_NAME
This means the queue name you are attempting to open does not exist on the queue manager you are connected to.
I noted that the source you posted does not include any code related to opening the queue. You should check that the queue name you are attempting to open does in fact exist on the queue manager you are connecting to.
We use a windowsservice which initializes and starts quartz jobs.
Everything works fine on the application servers so when I start the service, the jobs and triggers get scheduled and execute at the exact start time.
I now tried to install the windows service locally on my pc to test something but when I start it and quartz tries to initialize, the following error message appears in our log files:
only one usage of each socket address is normally permitted
The code where the error occurs is the following:
var properties = SetupDefaultProperties();
properties["quartz.plugin.xml.fileNames"] = "~/quartz_jobs.xml";
properties["quartz.scheduler.exporter.type"] = "Quartz.Simpl.RemotingSchedulerExporter, Quartz";
properties["quartz.scheduler.exporter.port"] = "555";
properties["quartz.scheduler.exporter.bindName"] = "QuartzScheduler";
properties["quartz.scheduler.exporter.channelType"] = "tcp";
properties["quartz.scheduler.exporter.channelName"] = "httpQuartz";
properties["quartz.scheduler.exporter.rejectRemoteRequests"] = "true";
var sf = new StdSchedulerFactory(properties);
return sf.GetScheduler();
Have you experienced something like this before and know how to fix it?
Is something blocking port 555?
Can I just use another port or does it have to be port 555 (UDC/TCP)
You can change the port in your config file (or in your case, in your properties) without any issues. Make sure you update your firewall rules to allow access to it though.
I want to use my remote to activate a function on my c# application via TCP/IP.
I have a program running on my remote that has a code like this, which sends the string "turnoff" to a TCP/IP server client: The 10.1.1.17 is the local ip of the computer, and the 898 is the port that is listening for incoming things.
socket1 = socket.connect("10.1.1.17", 898)
socket.send(socket1, "turnoff\n")
Firstly, how do I use this string of text, 'hello', to activate a function in my .net c# application? For example, if I send the string of 'turnoff', and I have a function in the c# app called 'turnoff()', how do I call this function.
One idea I had was to create a textbox and have the program read the text from the 'recieved data' box and if it is recognized, activate the necessary function. A program that would look something like this: http://gyazo.com/5419901b55fcf404a627b67bdee492f5 . How do I recreate this?
But, this doesn't seem like the most efficient method, reading strings from a textbox. Surely there is another way to read the "hello" message or any string into the c# program and activate a function within it.
Also, how do I create a TCP/IP server in C# with an port that listens for incoming strings and can send things back to the client connecting to it? For example, if I connect to the c# server with my remote, and I press a button on the C# form to send a string back to the remote. Is this called asynchronous or something, I'm not really sure.
Thanks.
You can use my open source library.
The server
As a server you typically just create a ChannelTcpListener:
var settings = new ChannelTcpListenerConfiguration(
() => new MicroMessageDecoder(new DataContractSerializer()),
() => new MicroMessageEncoder(new DataContractSerializer())
);
var server = new MicroMessageTcpListener(settings);
server.MessageReceived = OnServerMessage;
server.Start(IPAddress.Any, 1234);
That’s it, all you need now is a callback to receive messages from all clients:
private static void OnServerMessage(ITcpChannel channel, object message)
{
var command = (DeviceCommand) message;
//do something with the command
}
The client
In the client you do about the same, but you use async/await instead of a callback.
private static async Task RunClient()
{
var client = new ChannelTcpClient<object>(
new MicroMessageEncoder(new DataContractSerializer()),
new MicroMessageDecoder(new DataContractSerializer())
);
await client.ConnectAsync(IPAddress.Parse("192.168.1.3"), 1234);
await client.SendAsync(new DeviceCommand("turnoff"));
await client.CloseAsync();
}
Install the nuget package "griffin.framework" to use it. Code available at github
I have the following scenario:
My main Application (APP1) starts a Process (SERVER1). SERVER1 hosts a WCF service via named pipe. I want to connect to this service (from APP1), but sometimes it is not yet ready.
I create the ChannelFactory, open it and let it generate a client. If I now call a method on the generated Client I receive an excpetion whitch tells me that the Enpoint was not found:
var factory = new ChannelFactory<T>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe//localhost/myservice");
factory.Open()
var Client = factory.CreateChannel();
Client.Foo();
If I wait a little bit before calling the service, everything is fine;
var Client = factory.CreateChannel();
Thread.Sleep(2000);
Client.Foo();
How can I ensure, that the Service is ready without having to wait a random amount of time?
If the general case is that you are just waiting for this other service to start up, then you may as well use the approach of having a "Ping" method on your interface that does nothing, and retrying until this starts responding.
We do a similar thing: we try and call a ping method in a loop at startup (1 second between retries), recording in our logs (but ultimately ignoring) any TargetInvocationException that occur trying to reach our service. Once we get the first proper response, we proceed onwards.
Naturally this only covers the startup warmup case - the service could go down after a successfull ping, or it we could get a TargetInvocationException for a reason other than "the service is not ready".
You could have the service signal an event [Edited-see note] once the service host is fully open and the Opened event of the channel listener has fired. The Application would wait on the event before using its proxy.
Note: Using a named event is easy because the .NET type EventWaitHandle gives you everything you need. Using an anonymous event is preferable but a bit more work, since the .NET event wrapper types don't give you an inheritable event handle. But it's still possible if you P/Invoke the Windows DuplicateHandle API yourself to get an inheritable handle, then pass the duplicated handle's value to the child process in its command line arguments.
If you're using .Net 4.0 you could use WS-Discovery to make the service announce its presence via Broadcast IP.
The service could also send a message to a queue (MSMQ binding) with a short lifespan, say a few seconds, which your client can monitor.
Have the service create a signal file, then use a FileSystemWatcher in the client to detect when it gets created.
Just while (!alive) try { alive = client.IsAlive(); } catch { ...reconnect here... } (in your service contract, you just have IsAlive() return true)
I have had the same issue and when using net.pipe*://localhost/serviceName*, I solved it by looking at the process of the self-hosted application.
the way i did that was with a utility class, here is the code.
public static class ServiceLocator
{
public static bool IsWcfStarted()
{
Process[] ProcessList = Process.GetProcesses();
return ProcessList.Any(a => a.ProcessName.StartsWith("MyApplication.Service.Host", StringComparison.Ordinal));
}
public static void StartWcfHost()
{
string path = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var Process2 = new Process();
var Start2 = new ProcessStartInfo();
Start2.FileName = Path.Combine(path, "Service", "MyApplication.Service.Host.exe");
Process2.StartInfo = Start2;
Process2.Start();
}
}
now, my application isn't called MyApplication but you get my point...
now in my client Apps that use the host i have this call:
if (!ServiceLocator.IsWcfStarted())
{
WriteEventlog("First instance of WCF Client... starting WCF host.")
ServiceLocator.StartWcfHost();
int timeout=0;
while (!ServiceLocator.IsWcfStarted())
{
timeout++;
if(timeout> MAX_RETRY)
{
//show message that probably wcf host is not available, end the client
....
}
}
}
This solved 2 issues,
1. The code errors I had wend away because of the race condition, and 2
2. I know in a controlled manner if the Host crashed due to some issue or misconfiguration.
Hope it helps.
Walter
I attached an event handler to client.InnerChannel.faulted, then reduced the reliableSession to 20 seconds. Within the event handler I removed the existing handler then ran an async method to attempt to connect again and attached the event handler again. Seems to work.