Connecting to Websocket on shared hosting when port is blocked - c#

I built a program in c# (asp.net) that connects to wss://stream.binance.com:9443/ws using WebSocket4Net, and gets ticker data which is public.
My application runs fine on localhost, but on my hosting provider I get an error "An attempt was made to access a socket in a way forbidden by its access permissions" which is an issue of blocked port if I understand correctly.
My hosting provider allows me to enable specific ports for specific ip addresses, but in this case I don't have the ip address for the remote host wss://stream.binance.com:9443/ws
Is there a way to find out the ip address of the remote host when connection is open or when a message is received?
My code:
using System.Collections.Generic;
using Newtonsoft.Json;
using WebSocket4Net;
public static class BinanceWShandler
{
static WebSocket ws;
internal static bool isOpen { get; private set; }
public static void Start()
{
ws = new WebSocket("wss://stream.binance.com:9443/ws");
ws.Opened += Ws_Opened;
ws.Closed += Ws_Closed;
ws.Error += Ws_Error;
ws.MessageReceived += Ws_MessageReceived;
ws.EnableAutoSendPing = true;
ws.Open();
}
private static void Ws_Error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
{
}
private static void Ws_Closed(object sender, EventArgs e)
{
}
private static void Ws_Opened(object sender, EventArgs e)
{
Request_Individual_Ticker obj = new Request_Individual_Ticker();
obj.method = "SUBSCRIBE";
List<string> pars = new List<string>();
pars.Add("!bookTicker");
obj.#params = pars;
obj.id = 1;
string JSONstring = JsonConvert.SerializeObject(obj);
ws.Send(JSONstring);
isOpen = true;
}
private static void Ws_MessageReceived(object sender, MessageReceivedEventArgs e)
{
SignalRChat.Hubs.ChatHub.instance.SendBinanceWS(e.Message);
}
public class Request_Individual_Ticker
{
public string method { get; set; }
public List<string> #params { get; set; }
public int id { get; set; }
}
}

Related

websocket-sharp-customheaders send headers

I´ve installed nuget package websocket-sharp-customheaders for my WebSocket application and want to send a sessionId within the http-header-information.
Client-Code:
public class SocketController
{
public static readonly string ConnectionString = "ws://localhost:{0}/{1}";
private string sessionId;
public WebSocket NotificationSocket { get; private set; }
public SocketController(ServiceConfiguration config)
{
NotificationSocket = new WebSocket(string.Format(ConnectionString, config.Port, "Notify"));
}
public void Connect()
{
NotificationSocket.Connect();
}
public void SendNotification(string sessionId, Notification data)
{
if (NotificationSocket.ReadyState == WebSocketState.Open)
{
NotificationSocket.CustomHeaders = new Dictionary<string, string> { { "SessionId", sessionId } };
NotificationSocket.Send(data.SerializeJson());
}
}
public void SetNotificationSocketOnMessage(Action<NotifyMessage> onMessage)
{
NotificationSocket.OnMessage += (sender, e) => onMessage(e.Data.DeserializeJson<NotifyMessage>());
}
public void Stop()
{
NotificationSocket.Close();
}
}
In SendNotification the header is set. But the server doesn´t receive the header information.
Server Socket Behavior:
public class NotifyService : WebSocketBehavior
{
protected override void OnMessage(MessageEventArgs e)
{
var command = e.Data;
if (!Context.Headers.Contains("SessionId"))
return;
// Stuff todo with SessionId and Data
}
}
May someone tell me how to properly send header-information?
https://github.com/sta/websocket-sharp/pull/22
I believe they don't allow this.

Converting Client String to Array on Server C#

I want to convert the string the server is receiving from the client to in an array. However when I use the String.Split method the result variable is showing null. Anyone know why that might be?
namespace ExampleLib.Server
{
public class Server
{
private class ConnectedClient
{
public int ID { get; }
private TcpClient _client;
private StreamReader _streamReader;
public delegate void NetDataEventHandler(object sender, NetDataEventArgs e);
public event NetDataEventHandler NetData;
public virtual void OnNetData(NetDataEventArgs e)
{
NetData?.Invoke(this, e);
}
public class NetDataEventArgs
{
public NetDataEventArgs(int id, string message)
{
ID = id;
Message = message;
}
public string Message { get; }
public int ID { get; }
}
public ConnectedClient(int id, TcpClient client)
{
ID = id;
_client = client;
}
private void ClientReceiveData(object sender, ConnectedClient.NetDataEventArgs e)
{
if (string.IsNullOrEmpty(e.Message) == false)
{
Trace.WriteLine($" Client {e.ID}: {e.Message}");
var result = e.Message.Split(',');
}
}
You have stopped at the break-point.
You should proceed one more step, in order for that line to be executed.
Currently, you're at a step similar to this.
If you proceed one more step using F10 (or 'Step Over' button) , it will execute that line and assign the value of addition to c in this example.

Problems with receiving UDP messages in Metro-Apps

I'm currently working on a project and one of the featured devices is a Windows Tablet. To "connect" it to other devices (like some Raspberry Pi) in the project environment UDP is used to send messages. The Windows Tablet is intended to be some controlling device with soem touch functionality. Therefore I'm writing an App (and the intention of the App is not to put it into the Windows Store). The UDP part in this work is quite painful because I had to do much research since I started with no experience in App programming. More painful than the programming is, that I practically finished the work only to start over again because the App didn't receive UDP anymore.
Here's my code (I removed elements not relevant to the actual problem). I apologize for the bad coding....
App.xaml.cs:
sealed partial class App : Application
{
NetworkInterface ni = new NetworkInterface();
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
ni.MessageReceived += OnMessageReceived;
ni.Connect(new HostName("127.0.0.1"), "5556");
}
private void OnMessageReceived(object sender, MessageReceivedEventArgs e)
{
Debug.WriteLine("Processing");
Debug.WriteLine(e.Message.Data);
}
public static new App Current
{
get { return Application.Current as App; }
}
private DatagramSocket _socket;
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Update_Timer();
}
DispatcherTimer timer = new DispatcherTimer();
private void Update_Timer()
{
timer.Start();
timer.Interval = new TimeSpan(0,0,0,0,500);
timer.Tick += alive;
}
private void alive(object sender, object e)
{
if (start == 0) {
Debug.WriteLine("App-Startup");
ni.SendMessage("Startup...");
start++;
}
else
{
Debug.WriteLine("App-Alive");
ni.SendMessage("alive");
start++;
}
}
}
This part of code is to send and receive Messages in the backgrond in the whole App.
And a NetworkInterface class:
class NetworkInterface
{
private DatagramSocket _socket;
public bool IsConnected { get; set; }
public NetworkInterface()
{
IsConnected = false;
_socket = new DatagramSocket();
_socket.MessageReceived += OnSocketMessageReceived;
}
public async void Connect(HostName remoteHostName, string remoteServiceNameOrPort)
{
if (IsConnected != true)
{
await _socket.BindServiceNameAsync("5321");
await _socket.ConnectAsync(remoteHostName, remoteServiceNameOrPort);
}
IsConnected = true;
}
public void alive(object sender, object e)
{
Debug.WriteLine("alive");
}
public event EventHandler<MessageReceivedEventArgs> MessageReceived;
private void OnSocketMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
var reader = args.GetDataReader();
var count = reader.UnconsumedBufferLength;
var data = reader.ReadString(count);
Debug.WriteLine(args);
if (MessageReceived != null)
{
var ea = new MessageReceivedEventArgs();
ea.Message = new Message() { Data = data };
ea.RemoteHostName = args.RemoteAddress;
ea.RemotePort = args.RemotePort;
MessageReceived(this, ea);
}
}
DataWriter _writer = null;
public async void SendMessage(string message)
{
if (_writer == null)
{
var stream = _socket.OutputStream;
_writer = new DataWriter(stream);
}
_writer.WriteString(message);
await _writer.StoreAsync();
}
}
The main problems are:
If I dont send something before receiving, I won't be able top get an message.
If I send before I have random Faults at this line:
var reader = args.GetDataReader();
If nothing fails, I'm not able to receive messages from a local Python script (which works) but I can send messages from a local program which the App receives.
Does anyone know how I can fix these problems?
Thanks in advance!

Console C# check for internet availability and wait until it is not available

I have been searching for the code which will help me if the internet connection breaks in between.
I am having a console app which takes data from database and sends mail in bulk. Now while sending mails if internet connection fails than I want to wait until internet is available.
I got good ans here
public static void ConnectToPUServer()
{
var client = new WebClient();
while (i < 500 && networkIsAvailable)
{
string html = client.DownloadString(URI);
//some data processing
Console.WriteLine(i);
i++;
URI = "http://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/" + i + "/";
}
Console.WriteLine("Complete.");
writer.Close();
}
static void NetworkChange_NetworkAvailabilityChanged(object sender,NetworkAvailabilityEventArgs e)
{
networkIsAvailable = e.IsAvailable;
if (!networkIsAvailable)
{
Console.WriteLine("Internet connection not available! We resume as soon as network is available...");
}
else
{
ConnectToPUServer();
}
}
This is not exactly what I want. But I want to apply something similar to this. Can anybody help me how to implement this? I mean what is ConnectToPUServer and when NetworkChange_NetworkAvailabilityChanged will be executed and what namespace to be used?
you can use the below mentioned code for it you have to use
using System.Net.NetworkInformation;
public partial class MainWindow : Window
{
public bool IsAvailable { get; set; }
public MainWindow()
{
InitializeComponent();
NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
}
void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
{
IsAvailable = e.IsAvailable;
}
private void BrowseButton_Click(object sender, RoutedEventArgs e)
{
if (IsAvailable)
{
WebBrowser1.Navigate(TextBox1.Text);
}
else
{
MessageBox.Show("Your Popup Message");
}
}
}

WCF Basic WinForm App Communication Issue

All, I have extended this tutorial to get and reverse string displayed in two seperate WinForm applications. However, the end goal is to get this working between to WinForm apps that pass SQL between eachother. To facilitate this I have extended this example and the following is what I have
A library .dll containing
public class WcfInterface
{
private static WcfInterface instance;
private ServiceHost host;
private const string serviceEnd = "Done";
protected WcfInterface()
{
}
public static WcfInterface Instance()
{
if (instance == null)
instance = new WcfInterface();
return instance;
}
public void OpenServiceHost<T, U>()
{
host = new ServiceHost(typeof(U), new Uri[] { new Uri("net.pipe://localhost") });
host.AddServiceEndpoint(typeof(T), new NetNamedPipeBinding(), serviceEnd);
host.Open();
}
public void CloseServiceHost<T>()
{
host.Close();
}
public T AddListnerToServiceHost<T>()
{
ChannelFactory<T> pipeFactory =
new ChannelFactory<T>(new NetNamedPipeBinding(),
new EndpointAddress(String.Format("net.pipe://localhost/{0}",
serviceEnd)));
T pipeProxy = pipeFactory.CreateChannel();
return pipeProxy;
}
}
So on the 'server' form, I do
private void Form1_Load(object sender, EventArgs e)
{
List<string> sqlList = new List<string>();
foreach (string line in this.richTextBoxSql.Lines)
sqlList.Add(line);
SqlInfo sqlInfo = new SqlInfo(sqlList);
WcfInterface wcfInterface = WcfInterface.Instance();
wcfInterface.OpenServiceHost<ISqlListing, SqlInfo>();
}
Where
public class SqlInfo : ISqlListing
{
private List<string> sqlList;
public SqlInfo(List<string> sqlList)
{
this.sqlList = sqlList;
}
public List<string> PullSql()
{
return sqlList;
}
}
[ServiceContract]
public interface ISqlListing
{
[OperationContract]
List<string> PullSql();
}
In the client WinForm app
private ISqlListing pipeProxy;
public Form1()
{
InitializeComponent();
WcfInterface wcfInterface = WcfInterface.Instance();
pipeProxy = wcfInterface.AddListnerToServiceHost<ISqlListing>();
}
and on the click event I attampt to get the List<string> from the server
private void button1_Click(object sender, EventArgs e)
{
this.richTextBoxSql.Text = pipeProxy.PullSql().ToString(); // Code hangs here.
}
My question is what is wrong with this?
Thanks for your time.
Edit. I have now also changed the client code according to comments as follows
private ISqlListing pipeProxy { get; set; }
private const string serviceEnd = "Done";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.richTextBoxSql.Text = pipeProxy.PullSql().ToString();
}
private void Form1_Load(object sender, EventArgs e)
{
ChannelFactory<ISqlListing> pipeFactory =
new ChannelFactory<ISqlListing>(
new NetNamedPipeBinding(),
new EndpointAddress(
String.Format("net.pipe://localhost/{0}", serviceEnd)));
pipeProxy = pipeFactory.CreateChannel();
}
this also hangs on the click event.
The way you have the code set up, you are creating a WCF server on the client by referencing WcfInterface.Instance. You are then calling it from the same thread that it is being served on, causing your application to lock up.
There are a number of ways to get around this. Here are a few that come to mind:
Get the service running in your first WinForm app, then use the "Add Service Reference" functionality in visual studio to create your proxies. Note that you'll have to
You can still reference a common library for the WCF contracts, but rework your code so that you're not creating an instance of the service in your "client" WinForms app.

Categories