Client Creation using WebSocketSharpAPI - C# - c#

Hi StackOverflow Members,
I have created an HTTP server using WebsocketsharpAPI https://github.com/sta/websocket-sharp.
Here I have created an HTTP address = "http://localhost:0001/MoviePage";
I am then, Initializing and creating the Httpserver and starting it under the
Subquery /MoviePage . Here to test if client is receiving data in first place, I am sending a string of movie name instead of movie object that I have
Server.WebSocketServices[DisplayCollimationPort].Sessions.Broadcast("Spider Man 2");
The Server works without any issue. However, the issue is - I am not sure, How to use this
Websocketsharp API to Create a client and receive the sent string via a broadcast function from the server.
The examples are given only harnessing(or maybe I am missing something) the Websocketserver and Websocket class for the Server and Client in the examples provides.
Now since my address is an HTTP one and not a (ws or wss) (WebSocket) one, I would like to know if I can still use this websocketsharp API to implement a client to fetch string sent in this URL and access it. This is also because I would not be able to receive the information from httpserver with Websocket class.
Any suggestions would be much appreciated.
Thanks in Advance !!

Related

How to send updates from server to clients?

I am building a c#/wpf project.
It's architecture is this:
A console application which will be on a virtual machine (or my home computer) that will be the server side.
A wpf application that will be the client app.
Now my problem is this - I want the server to be able to send changes to the clients. If for example I have a change for client ABC, I want the server to know how to call a service on the clients computer.
The problem is, that I don't know how the server will call the clients.
A small example in case I didn't explain it well:
The server is on computer 1, and there are two clients, on computers 2 and 3.
Client 2 has a Toyota car and client 3 has a BMW car.
The server on computer 1 wants to tell client 2 that it has a new car, an Avenger.
How do I keep track and call services on the clients?
I thought of saving their ip address (from calling ipconfig from the cmd) in the DB - but isn't that based on the WI-FI/network they are connected to?
Thanks for any help!
You could try implementing SignalR. It is a great library that uses web sockets to push data to clients.
Edit:
SignalR can help you solve your problem by allowing you to set up Hubs on your console app (server) that WPF application (clients) can connect to. When the clients start up you will register them with a specified Hub. When something changes on the server, you can push from the server Hub to the client. The client will receive the information from the server and allow you to handle it as you see fit.
Rough mockup of some code:
namepsace Server{}
public class YourHub : Hub {
public void SomeHubMethod(string userName) {
//clientMethodToCall is a method in the WPF application that
//will be called. Client needs to be registered to hub first.
Clients.User(userName).clientMethodToCall("This is a test.");
//One issue you may face is mapping client connections.
//There are a couple different ways/methodologies to do this.
//Just figure what will work best for you.
}
}
}
namespace Client{
public class HubService{
public IHubProxy CreateHubProxy(){
var hubConnection = new HubConnection("http://serverAddress:serverPort/");
IHubProxy yourHubProxy = hubConnection.CreateHubProxy("YourHub");
return yourHubProxy;
}
}
}
Then in your WPF window:
var hubService = new HubService();
var yourHubProxy = hubService.CreateHubProxy();
yourHubProxy.Start().Wait();
yourHubProxy.On("clientMethodToCall", () => DoSometingWithServerData());
You need to create some kind of subscription model for the clients to the server to handle a Publish-Subscribe channel (see http://www.enterpriseintegrationpatterns.com/patterns/messaging/PublishSubscribeChannel.html). The basic architecture is this:
Client sends a request to the messaging channel to register itself as a subscriber to a certain kind of message/event/etc.
Server sends messages to the channel to be delivered to subscribers to that message.
There are many ways to handle this. You could use some of the Azure services (like Event hub, or Topic) if you don't want to reinvent the wheel here. You could also have your server application track all of these things (updates to IP addresses, updates to subscription interest, making sure that messages don't get sent more than once; taking care of message durability [making sure messages get delivered even if the client is offline when the message gets created]).
In general, whatever solution you choose is plagued with a common problem - clients hide behind firewalls and have dynamic IP addresses. This makes it difficult (I've heard of technologies claiming to overcome this but haven't seen any in action) for a server to push to a client.
In reality, the client talks and the server listens and response. However, you can use this approach to simulate a push by;
1. polling (the client periodically asks for information)
2. long polling (the client asks for information and the server holds onto the request until information arrives or a timeout occurs)
3. sockets (the client requests server connection that is used for bi-directional communication for a period of time).
Knowing those terms, your next choice is to write your own or use a third-party service (azure, amazon, other) to deliver messages for you. I personally like long polling because it is easy to implement. In my application, I have the following setup.
A web API server on Azure with and endpoint that listens for message requests
A simple loop inside the server code that checks the database for new messages every 100ms.
A client that calls the API, handling the response.
As mentioned, there are many ways to do this. In your particular case, one way would be as follows.
Client A calls server API to listen for message
Server holds onto call, waiting for new message entry in database
Client B calls server API to post new message
Server saves message to database
Server instance from step 2 sees new message
Server returns message to Client A.
Also, the message doesn't have to be stored in a database - it just depends on your needs.
Sounds like you want to track users à la https://www.simple-talk.com/dotnet/asp.net/tracking-online-users-with-signalr/ , but in a desktop app in the sense of http://www.codeproject.com/Articles/804770/Implementing-SignalR-in-Desktop-Applications or damienbod.wordpress.com/2013/11/20/signalr-a-complete-wpf-client-using-mvvm/ .

Feed subscription of a Page

I want to get notifications when a new feed has landed on a designated page (by page id). After what I understand, the Realtime-update og Graph API should be able to do this trick according to https://developers.facebook.com/docs/graph-api/real-time-updates/v2.4.
So I want to add a new subscription, which I try to do with the following code:
dynamic result = client.Post(urlPath, new
{
#object = "page",
callback_url = callbackUrl,
fields = "feed",
verify_token = "654321",
access_token = accessToken
});
return result;
But when I try to run this, I'm getting the following error code:
(OAuthException - #2200) (#2200) callback verification failed: Received HTTP code 502 from proxy after CONNECT"
What do I miss?
The callback url is https://127.0.0.1:8989/ and I have a TcpListener running on the port, which does not seem to get any response/request incoming...
The application is a C# console application, so no fancy asp.net stuff or something. I'm using the Facebook .net SDK.
Should I FacebookClient.VerifyPostSubscription() or anything else that I missed out?? Maybe the SDK wraps a handle?
So the answer I'm looking for is:
- How do I create/add a subscription for feeds of a facebook page, using the .net SDK on a windows console project??
UPDATE:
I changed the loopback with a domain name, that I the NAT to my target machine, and now I actually get some encrypted data on my TcpListener!
So, the question now is, how do I respond correctly to this received respons, only by using a Tcp Client??
How you have to respond is exactly outlined in the docs you linked:
https://developers.facebook.com/docs/graph-api/real-time-updates/v2.4#setupget
It's not really clear what you mean with "TCP listener". You need to have some logic why can send HTTP responses to the Facebook servers, otherwise your service will be disregarded after some time, meaning no updates will be send.
Typically, this is implemented as a script/application in a web/application server.
Please note: The "C# SDK" is a third-party SDK and not officially supported by FB.

Communicating with a classic TCP socket

I'm writing my first application with NetMQ (ZeroMQ implementation for .NET).
I also need to listen to information sent from a client using a traditional TCP socket (a.k.a a non-0MQ socket).
I've seen references to the availability of this socket type in the official ZeroMQ documentation here, (look for ZMQ_STREAM), but there's very few details on how to use it (and that doesn't help much either, the .NET API is quite a bit different from the C++ API).
The offical NetMQ documentation also makes no mention of the Streaming socket type.
Finally I had a look over to the Test suite for NetMQ on Github, and found a partial answer to my question in the method RawSocket.
The following snippet works:
using (NetMQContext context = NetMQContext.Create())
{
using (var routerSocket = context.CreateRouterSocket())
{
routerSocket.Options.RouterRawSocket = true;
routerSocket.Bind("tcp://127.0.0.1:5599");
byte[] id = routerSocket.Receive();
byte[] message = routerSocket.Receive();
Console.WriteLine(Encoding.ASCII.GetString(id));
Console.WriteLine(Encoding.ASCII.GetString(message));
}
}
When using standard TCP/IP test-tools, the byte[] message is printed out nicely, e.g. like this:
Hello World!
but the byte[] id is printed out like this:
???♥
In other words, I have no clue what's up with the id part. Why is routerSocket.Receive called twice? What is contained within the id? Is this something ZeroMQ/NetMQ specific, or is something TCP/IP specific information being extracted here?
Thanks to #Mangist for pointing this out.
The answer is in the RouterSocket documentation:
An identity, sometimes called an address, is just a binary string
with no meaning except "this is a unique handle to the connection".
Then, when you send a message via a ROUTER socket, you first send an
identity frame.
When receiving messages a ZMQ_ROUTER socket shall prepend a message
part containing the identity of the originating peer to the message
before passing it to the application. Messages received are
fair-queued from among all connected peers. When sending messages a
ZMQ_ROUTER socket shall remove the first part of the message and use
it to determine the identity of the peer the message shall be routed
to.
Identities are a difficult concept to understand, but it's essential
if you want to become a ZeroMQ expert. The ROUTER socket invents a
random identity for each connection with which it works. If there are
three REQ sockets connected to a ROUTER socket, it will invent three
random identities, one for each REQ socket.
This image illustrates the core concept of the ID frames:

Update data on client side by server push

I'm using wcf. I have a simple method in web service that retrieves some string data from database and returns that string data to client.
public string getSomeStringfromDatabase(){
string s ="";
//retrieving from database logic into string s
return s;
}
Really simple method, nothing special..
Now I would like to learn how to use this method to update that string from database on my clients side by "server push" style or how it is called.
Can someone give me a simple example?
I read some topics on internet pushing vs polling, but couldn't find simple enough code to understand it.
Can you give an example of push with web service method and polling too if it's not too much?
have you looked at SignalR. Its a server Push Framework which uses HTML5 WWeb Socket beneath. I have created chat server here using SignalR.
https://github.com/omkarpanhalkar/AjaxChatRoom

Ensuring that outgoing WCF requests are performed using a specific network interface

I have a remote WCF web service that I'm connecting to from my application.
The application may be running on a server with multiple IP addresses (or multiple physical network interfaces)
I need to make sure that I can control which IP address is being used for the outbound request, instead of just using the 'preferred' interface as per the normal metric rules.
The reason for this is that multiple copies of the software will be running on the same machine, each bound to a specific IP address for its own operations, and the remote service being connected to needs to know which one is being used to connect back to it at a later time (since getting the address wrong means connecting to the wrong service)
With legacy ASMX services this is done by overriding GetWebRequest(Uri uri) on the partial class generated for the service. But I cannot figure out at all how to do this with WCF.
On an unrelated SO post, MVP #JohnSaunders suggested this may be possible by taking over the entire transport mechanism used by WCF. But I've not yet figured out how to do this either.
This is a tricky problem, which WCF doesn't seem to cater for particularly well.
The only component in the .NET framework that seems to directly deal with the issue of the client address is the ServicePoint class. Specifically, it has a BindIPEndPointDelegate property which lets you control how it selects the client IP. The documentation for the property includes this:
Some load balancing techniques require a client to use a specific local IP address and port number, rather than IPAddress.Any (or IPAddress.IPv6Any for Internet Protocol Version 6) and an ephemeral port. Your BindIPEndPointDelegate can satisfy this requirement.
Thus, you should be able to modify the service point associated with your URL in code like this:
var servicePoint = ServicePointManager.FindServicePoint(
new Uri("http://contoso.com/service.svc"));
servicePoint.BindIPEndPointDelegate =
(sp, remote, retryCount) => new IPEndPoint(address, portNumber);
Obviously this kind of code requires your classes have awareness of the protocol and the endpoint address the client will be communicating with. It would likely be most appropriate to set up this logic as a client behaviour which can be applied to your client channel.
you can use a message property (HttpRequestMessageProperty) to add HTTP headers to any outgoing requests. You need to create a "scope" in which the property will be added to the current "operation context", and attach the property, with all headers you want, to the outgoing message properties of the context.
please look at this :
how-to-override-getwebrequest-method-using-service-reference-instead-of-web-reference-in-wcf
Use this:
New Class:
using System.Web.Services.Protocols;
using System.Windows.Forms;
using System;
public static class ExtensionMethods
{
public static string ApplyServerURL(this SoapHttpClientProtocol service)
{
try
{
string name = service.GetType().Name;
return string.Format("{0}{1}.svc", Settings.Instance.ServerAddress, name);
}
catch
{ return string.Empty; }
}
}
And now is something like this:
YourService us = new YourService();
us.Url = us.ApplyServerURL();

Categories

Resources