Scrape data from WebSocket with C# .Net - c#

I need to scrape data from a websocket "just one time".
I mean that I don't need to get continuosly data from the source but I need
to get the data one time and exit from the elaboration.
I don't need Async task, I just need to use it like a simple API.
I'm struggling with web search but I didn't find any solution.
Thanks to support

I think your are struggling to find such code as websocket is almost a bi-directional protocol, not really for a RPC style.
But to answer your need, you could certainly use a library such as websocket-sharp . Your code to send a command text and receive back a return message would look like this :
using System;
using WebSocketSharp;
namespace Example
{
public class Program
{
public static void Main (string[] args)
{
using (var ws = new WebSocket ("ws://YOUR_URI_HERE")) {
ws.OnMessage += (sender, e) =>
Console.WriteLine ("It's ok I got my answer back : " + e.Data);
ws.Connect ();
ws.Send ("COMMAND FOR THE SERVER");
Console.ReadKey (true);
}
}
}
}
Hope that code will help you to get started.

Related

PHP C# Named Pipes

I recently asked a question on IPC between C# and PHP and followed an answer up suggesting named pipes. For this, I searched the Internet for an appropriate example of named pipes using solely C# as client and server simultaneously and modified it so it'd run asynchronously:
static void Main(string[] args)
{
Start();
new AutoResetEvent(false).WaitOne();
}
private static async void Start()
{
StartServer();
Thread.Sleep(1500);
StartClient();
}
private static async void StartClient()
{
var client = new NamedPipeClientStream("TestPipe");
await client.ConnectAsync();
var reader = new StreamReader(client);
var writer = new StreamWriter(client);
while (true)
{
var input = Console.ReadLine();
if (string.IsNullOrEmpty(input)) break;
await writer.WriteLineAsync(input);
await writer.FlushAsync();
Console.WriteLine(await reader.ReadLineAsync());
}
}
private static async void StartServer()
{
await Task.Run(async() =>
{
var server = new NamedPipeServerStream("TestPipe");
await server.WaitForConnectionAsync();
var reader = new StreamReader(server);
var writer = new StreamWriter(server);
while(true) // should be !reader.EndOfStream(), doesn't work tho
{
var line = await reader.ReadLineAsync();
await writer.WriteLineAsync("RECEIVED > " + line);
await writer.FlushAsync();
}
});
}
So if I now type Hello into the console, it is going to return RECEIVED > Hello, which is fine and looks like it's brilliantly working. I entirely understand this in C#. However, this changes when PHP comes into play: I found less good examples (or even tutorials) for named pipes in PHP and the usage. Now what I found here brought me one step further, but only one.
In PHP, I seem to lack the understanding of the whole complex. My target is to 'feed' my C# server with tasks in the form of commands (e.g. create document id=12). The server (which is also running largely asynchronous) then shall give something back stating whether it has worked out or not (also using the id). So for example, my server's reply could be:
document id=12 created successfully
or
document id=12 error
Of course, I'll need my both applications to parse this and process these replies further, however, this is not the nub of the matter at this point. I need my PHP application to schedule tasks to C# and get the 'ping-back' ('error or not', you could say). I don't even need multiple ping backs, so for example a status update of the C# application frequently sending this, I only need one final statement whether it has worked or not.
Taking a look at the example I found on php.net, this does not tell me too much about it:
<?php
$pipe="/tmp/pipe";
$mode=0600;
if(!file_exists($pipe)) {
// create the pipe
umask(0);
posix_mkfifo($pipe,$mode);
}
$f = fopen($pipe,"w");
fwrite($f,"hello"); //block until there is a reader
unlink($pipe); //delete pipe
?>
And this is the non-blocking reader:
<?php
$pipe="/tmp/pipe";
if(!file_exists($pipe)) {
echo "I am not blocked!";
}
else {
//block and read from the pipe
$f = fopen($pipe,"r");
echo fread($f,10);
}
?>
The first, blocking variant, does not qualify for Windows since posix is not available on Windows and my C# application requires this. The example shows a blocked pipe (what exactly is this even? I could think of an existent pipe considered blocked, since if(!file_exists($pipe)) suggests this). However, this would mean that I could only handle one task at the same time with my C# server, which is not the requirement.
This is the procedure it is supposed to be:
User presses 'download'
PHP Action is fired (inside my Laravel Controller)
PHP schedules a task to the C# server via pipe
C# server receives it and processes it
C# server finishes it and tells PHP that it is finished (or error thrown, respectively) via pipe
The PHP (Laravel Controller) already awaits this answer and renders it to the user
Where I'm stuck is the point where pipes can be blocked, since this (according to the reference on the PHP docs page comments section) would mean if a certain pipe is blocked and I want multiple tasks to be ran at the same time, I need to create a new one, which my C# server must be aware of, too, which in conclusion means I can only set a very limited number of pipes, so to speak 'possible' slots for 'work' or 'tasks' of the server which a user of the web application can join into [the slot] and afterwards the slot's cleared. Howsoever, this'd destroy the concept of my C# asynchronous server and the principal idea behind it, and I can't think of this as the only solution.
I'm looking forward to seeing some suggestions. Cheers!

No result when performing port-forwarding

I am currently working with the UNet client-server system in order to do networking and in order to be able to search for all devices on a port beyond LAN as suggested by this previous question. After searching around I found a suitable C# port-forwarding library from this website and have been following the instructions in order to be able to discover devices on ports. So far I have turned those instructions into the code below.
using UnityEngine;
using System.Collections;
using Mono.Nat;
public class PortForwarding : MonoBehaviour {
void Start()
{
NatUtility.DeviceFound += DeviceFound;
NatUtility.DeviceLost += DeviceLost;
Debug.Log("Discovery Started");
NatUtility.StartDiscovery();
}
private void DeviceFound(object sender, DeviceEventArgs args)
{
Debug.Log("DeviceFound");
INatDevice device = args.Device;
device.CreatePortMap(new Mapping(Protocol.Udp, 10000, 10000));
// Can be .Udp or Tcp but both create no results
foreach (Mapping portMap in device.GetAllMappings())
{
Debug.Log(portMap.ToString());
}
// on device found code
}
private void DeviceLost(object sender, DeviceEventArgs args)
{
INatDevice device = args.Device;
// on device disconnect code
}
}
In my scene I have three empty GameObjects each with a script, one is to create a server, the second creates a client and the other is to test port-forwarding (the first two scripts are shown here). Unfortunately I am getting no result, hence today I am asking you where have I gone wrong and how could I use this library to discover clients or servers beyond LAN.
If I have missed any details out or you require more in order to solve my problem just ask.

Using Callback function provided by API, but get no results?(C#)

I'm using a API called WindAPI which provided the financial data from China markets. This API provides a method call wsq() which will provide the RealTime price data to user's program through a callback function!
I write some simple codes in c#,trying to use this wsq() method, but get no results. I wonder there must be some error in codes, but just can't find it!
I'm new to both C# and programming, so if it's a rookie mistake, don't laugh at me:)
Here's the codes, I'll give as much comments as possible, so you can find the misunderstanding in it quickly.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//-----------------------------
using WAPIWrapperCSharp; //the namespace in API dll(official provided)
using WindCommon; //the namespace to process the data formats (official provided)
namespace WSQ2String
{
class WSQ2StringSample
{
static void Main()
{
Console.Write("Begin......");
Console.ReadLine();
//--------------------creat the new API object and log on
WindAPI w = new WindAPI();
Console.WriteLine("New API created!");
w.start();
Console.WriteLine("API log on!");
//--------------------request for the realtime data through w.wsq() method
int errorId = 0;
ulong reqId = w.wsq(ref errorId, "150195.sz", "rt_date, rt_time, rt_lastest", "", myCallback);
Console.WriteLine("errorId = {0}", errorId);
//----adding a control line which will stop the main program and wait for myCallback function to be called
Console.ReadLine(); //after the data arrived, the test is over, and we press a key to let the main program continue
w.cancelRequest(reqId);
w.stop();
Console.Write("End......");
Console.ReadLine();
}
//----
static void myCallback(ulong reqId, WindData wd)
{
Console.WriteLine("wsq data gotback......");
//----transfer the official WindData format to String, and output to the screen
string s = WindDataMethod.WindDataToString(wd, "wsq"); //the method is in WindCommon namespace
Console.Write(s);
}
}
}
My understanding is that, when I request the data service by using w.wsq(), when the prices change(that's the event), myCallback() will be called and export the data on screen!
The reason I add a readline() is to prevent the main program runs too fast, and end before the event(price changing). In that situation, the myCallback() would have no chance to be called!
But when I run the codes, after "errorId = 0" shows, I wait several minutes and still get no results! I confirmed that the price has changed(it usually changed within seconds).
Here is the result I get, and I can't find the reason....(I just type the lines in screen)
>>Begin......
>>New API created!
>>API log on!
>>errorId = 0
and then the prgram just paused there and nothing more happened!
So I'd be very thankful if someone could explain that to me....
Thank you in advanced!
Updated:
According to the comments below, I give the zip files of my solutions.
Also with the API dll and it's source codes.
My solution files and dll
so, anyone help?

How can I send a "Message" to another process in .Net, without using SendMessage?

I have multiple applications running on a single machine. One is doing work and writing logs to disk about what it has done (I'll call this WorkerApp) and another that summarizes support information about the status of WorkerApp along with some more details (I'll call this Dashboard).
From the Dashboard i want to instruct the WorkerApp to take an action (say, "Ping remote services") and I would like the WorkerApp to send the Dashboard the "pong" response when it gets it.
I have seen examples of using the SendMessage, but this seems to be pretty archaic (isn't there anything more standard now in 2016 for between process communications?).
I have very little experience with Akka.Net but the Remoting feature of it seem like a good approach, although setting this up seems a little overkill for what I would like to do.
What is the easiest way currently to go about communicating between two processes in .Net? And is there some examples of this, working on a localmachine?
I put together an Akka.Net example for this. This is what it looks like.
DashBoard (sends messages)
using System;
using Akka.Actor;
using Akka.Configuration;
namespace DashBoard
{
class Program
{
static void Main(string[] args)
{
var config = ConfigurationFactory.ParseString(#"
akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
remote {
helios.tcp {
transport-class = ""Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote""
applied-adapters = []
transport-protocol = tcp
port = 0
hostname = localhost
}
}
}
");
using (var system = ActorSystem.Create("Dashboard", config))
{
var server = system.ActorSelection("akka.tcp://WorkerApp#localhost:8081/user/WorkerAppActor");
while (true)
{
var input = Console.ReadLine();
server.Tell(input);
}
}
}
}
}
WorkerApp (receives messages)
using System;
using Akka.Actor;
using Akka.Configuration;
namespace WorkerApp
{
class Program
{
static void Main(string[] args)
{
var config = ConfigurationFactory.ParseString(#"
akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
remote {
helios.tcp {
transport-class = ""Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote""
applied-adapters = []
transport-protocol = tcp
port = 8081
hostname = localhost
}
}
}
");
using (var system = ActorSystem.Create("WorkerApp", config))
{
system.ActorOf<WorkerAppActor>("WorkerAppActor");
Console.ReadLine();
}
}
}
class WorkerAppActor : TypedActor, IHandle<string>
{
public void Handle(string message)
{
Console.WriteLine($"{DateTime.Now}: {message}");
}
}
}
Have a look at .Net remoting. It's a bit more modern than SendMessage, but not a whole lot. It's pretty easy to use though. I think the official way to do this these days is probably using WCF, but I'm pretty sure it's just the same under the hood.
.Net remoting supports various channels (Http, TCP), but in your case I'd suggest IPC remoting. It sits on top of named pipes.
Probably easiest if you google (.Net remoting), but the general idea is to define a class in your "server" app derived from MarshalByRefObject. Once you've done that, register it with the remoting infrastructure using RemotingConfiguration.RegisterWellKnownServiceType.
Your client app can then create an instance of the class using Activator.CreateObject and then you're good to go.
One thing to be aware of: it looks like you'll want a callback mechanism - so your Dashboard isn't blocked waiting for your WorkerApp. This is supported in .Net remoting, but you'll need to create two channels - one for the outgoing calls (from Dashboard to WorkerApp) and then another for the incoming callbacks.
Another suggestion: your worker class (the one derived from MarshalByRefObject) will be easier to deal with if exposes an interface as well. Put that interface in a DLL available to both apps and life will be easier.
One suggestion may be to use a database or other persistent storage to create a type of 'Queue' which the dashboard can insert tasks into. This could also store statuses about the tasks which can be updated by the worker process. Although this could be considered 'overkill' it brings a vartiety of benefits such as auditing, historical reporting and server crash/power-off redundancy. It would also probably make scaling up the application in the future easier.

Send IM message to specific user in the conversation Lync 2013 SDK in UI suppression mode

I am trying to create a messaging app using Lync 2013 sdk in UI suppression mode, i am using the following code to send message to all participants in the conversation, but i can't find a way to send a message to specific one of them, do anyone know how to do this?
My Code:
public void StartIMConversation(string participantUri)
{
_Conversation.PropertyChanged += _Conversation_PropertyChanged;
_Conversation = _LyncClient.ConversationManager.AddConversation();
}
void ConversationsManager_ConversationAdded(Object source, ConversationManagerEventArgs data)
{
data.Conversation.ParticipantAdded += Conversation_ParticipantAdded;
data.Conversation.StateChanged += Conversation_StateChanged;
data.Conversation.AddParticipant(_LyncClient.ContactManager.GetContactByUri(this.myRemoteParticipantUri));
data.Conversation.AddParticipant(_LyncClient.ContactManager.GetContactByUri(this.myRemoteParticipantUri2));
data.Conversation.AddParticipant(_LyncClient.ContactManager.GetContactByUri(this.myRemoteParticipantUri3));
InstantMessageModality imModality = (InstantMessageModality)participant.Conversation.Modalities[ModalityTypes.InstantMessage];
imModality.BeginSendMessage(message, SendMessageCallback, imModality);
}
private void SendMessageCallback(IAsyncResult ar)
{
InstantMessageModality imModality = (InstantMessageModality)ar.AsyncState;
try
{
imModality.EndSendMessage(ar);
}
catch (LyncClientException lce)
{
MessageBox.Show("Lync Client Exception on EndSendMessage " + lce.Message);
}
}
if this can't be done using the conversation please guide me to the right way, any help appreciated.
There isn't a way to be selective of the recipients of an IM in a given conversation. Your best bet is probably to start a separate conversation with just the participants you need.
I agree with the selected answer ... but ... as you're writing a UI Suppression App, you can use a separate IM conversation (as per the answer) but then present it inline. As you're controlling the display of the conference, you can display it however you want, if that's really what you want to do.

Categories

Resources