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.
Related
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; }
}
}
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.
In the program you enter with a username brought from a database. I need to pass that username to another form but when I do it, it returns null in the second form although in the first form it appears.( "Jugador" is the class from where I bring the name).
public Usuario()
{
InitializeComponent();
}
private string _Message;
public string Message
{
get { return _Message; }
set { _Message = strName; }
}
public string strName;
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text!="")
{
Jugador jug = new Jugador();
jug.Traemelo(textBox1.Text);
strName = textBox1.Text;
elegirTipo us = new elegirTipo();
us.Show();
this.Hide();
}
}
And in my other form i have this.(Usuario is the first form)
private void silabas_Load(object sender, EventArgs e)
{
Usuario usu = new Usuario();
juga.Traemelo(usu.Message);
}
I've got to add that in the middle of these forms I pass by one but doens't need the variable there.
Thanks for the help! I really don't know what is happening because I've done this other times.
// Usuario.cs
public string Message { get; set; }
...
Silabas silabas = new Silabas(this);
// Silabas.cs
public Silabas(Usuario usuario)
{
// Here you can access the usuario.Message
}
What I personally would do is to create a static class and hold the values in it. This would also let me not to instantiate the class every time I need to use it.
public static class Jugador
{
//ctor if needed
public static string Username { get; set; }
}
Now, in your code where you both set or get the values of the username:
//login process
Jugador.Username = "some username";
//in application (get)
textbox1.Text = Jugador.Username;
I believe this is what you are looking for.
At a first glance:
public string Message
{
get { return _Message; }
set { _Message = value } // instead of strName;
}
no Message=something (set is never called)
_Message seems to compete with strName. One variable should be enough.
EDIT: Combined to this:
public Usuario()
{
InitializeComponent();
}
private string _Message;
public string Message
{
get { return _Message; }
set { _Message = value; }
}
private void button1_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(textBox1.Text))
{
Jugador jug = new Jugador();
jug.Traemelo(textBox1.Text);
Message = textBox1.Text;
elegirTipo us = new elegirTipo();
us.Show();
this.Hide();
}
}
Problem is since you are creating a new instance i.e. Usuario usu = new Usuario(); of the object in the other class, the value becomes null. I would use a static variable. In your Usuario class use
public static string strName{get;set;}
Now to set the value say Usuario.strName = textBox1.Text;
in your other class here say,
private void silabas_Load(object sender, EventArgs e)
{
juga.Traemelo(Usuario.strName);
}
I trying to allow people to write to NFC tags using my app, so that my app gets launched with a custom parameter. I want to be able to reprogram NFC tags which already have data on them.
I am using the following code but the problem is, that WP always recognizes the action which is already on the NFC tag and interrupts because it wants to launch the NFC tag action which was written anytime before.
How can I tell the OS to stop triggering the action of the tag so that I can immediately rewrite it?
public enum NfcHelperState
{
Initializing,
Waiting,
Ready,
Writing,
Finished,
Error,
NoDeviceFound
}
public class NfcHelper
{
private NfcHelperState _state = NfcHelperState.Initializing;
public NfcHelperState State
{
get { return _state; }
}
private ProximityDevice _nfcDevice;
private long _subscriptionId;
public NfcHelper()
{
Init();
}
public void Init()
{
UpdateState();
_nfcDevice = ProximityDevice.GetDefault();
if (_nfcDevice == null)
{
UpdateState(NfcHelperState.NoDeviceFound);
return;
}
UpdateState(NfcHelperState.Waiting);
}
private void UpdateState(NfcHelperState? state = null)
{
if (state.HasValue)
{
_state = state.Value;
}
if (OnStatusMessageChanged != null)
{
OnStatusMessageChanged(this, _state);
}
}
public void WriteToTag()
{
UpdateState(NfcHelperState.Ready);
_subscriptionId = _nfcDevice.SubscribeForMessage("WriteableTag", WriteableTagDetected);
}
private void WriteableTagDetected(ProximityDevice sender, ProximityMessage message)
{
UpdateState(NfcHelperState.Writing);
try
{
var str = "action=my_custom_action";
str += "\tWindowsPhone\t";
str += CurrentApp.AppId;
_nfcDevice.PublishBinaryMessage("LaunchApp:WriteTag", GetBufferFromString(str),
WriteToTagComplete);
}
catch (Exception e)
{
UpdateState(NfcHelperState.Error);
StopWaitingForTag();
}
}
private void WriteToTagComplete(ProximityDevice sender, long messageId)
{
sender.StopPublishingMessage(messageId);
UpdateState(NfcHelperState.Finished);
StopWaitingForTag();
}
private void StopWaitingForTag()
{
_nfcDevice.StopSubscribingForMessage(_subscriptionId);
}
private static IBuffer GetBufferFromString(string str)
{
using (var dw = new DataWriter())
{
dw.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE;
dw.WriteString(str);
return dw.DetachBuffer();
}
}
public delegate void NfcStatusMessageChangedHandler(object myObject, NfcHelperState newState);
public event NfcStatusMessageChangedHandler OnStatusMessageChanged;
}
WriteToTag is called when a button in my app is tapped and the app waits for a writable tag. If a writable tag is recognized, WriteableTagDetected gets called and immediately starts the writing process. However, this is interrupted by the WP dialog which asks whether to perform the NFC action or not. After writing, WriteToTagComplete should be called, where StopWaitingForTag gets called and ends the write process.
I hope you guys can help me :)
Turns out I thought the wrong way. I didn't need to wait for a tag to arrive in order to rewrite it. In fact, there's no need to do _nfcDevice.SubscribeForMessage("WriteableTag", WriteableTagDetected); before writing. Just start using PublishBinaryMessage and it will write to the tag once it arrives at the device.
My final code looks like the following:
public enum NfcHelperState
{
Initializing,
Ready,
WaitingForWriting,
FinishedWriting,
ErrorWriting,
NoDeviceFound
}
public class NfcHelper
{
private NfcHelperState _state = NfcHelperState.Initializing;
public NfcHelperState State
{
get { return _state; }
}
private ProximityDevice _nfcDevice;
private long? _writingMessageId;
public NfcHelper()
{
Init();
}
public void Init()
{
UpdateState();
_nfcDevice = ProximityDevice.GetDefault();
if (_nfcDevice == null)
{
UpdateState(NfcHelperState.NoDeviceFound);
return;
}
UpdateState(NfcHelperState.Ready);
}
private void UpdateState(NfcHelperState? state = null)
{
if (state.HasValue)
{
_state = state.Value;
}
if (OnStatusMessageChanged != null)
{
OnStatusMessageChanged(this, _state);
}
}
public void WriteToTag()
{
StopWritingMessage();
UpdateState(NfcHelperState.WaitingForWriting);
try
{
var str = new StringBuilder();
str.Append("action=my_custom_action");
str.Append("\tWindowsPhone\t{");
str.Append(CurrentApp.AppId);
str.Append("}");
_writingMessageId = _nfcDevice.PublishBinaryMessage("LaunchApp:WriteTag", GetBufferFromString(str.ToString()),
WriteToTagComplete);
}
catch
{
UpdateState(NfcHelperState.ErrorWriting);
StopWritingMessage();
}
}
private void WriteToTagComplete(ProximityDevice sender, long messageId)
{
UpdateState(NfcHelperState.FinishedWriting);
StopWritingMessage();
}
private void StopWritingMessage()
{
if (_writingMessageId.HasValue)
{
_nfcDevice.StopPublishingMessage(_writingMessageId.Value);
_writingMessageId = null;
}
}
private static IBuffer GetBufferFromString(string str)
{
using (var dw = new DataWriter())
{
dw.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE;
dw.WriteString(str);
return dw.DetachBuffer();
}
}
public delegate void NfcStatusMessageChangedHandler(object myObject, NfcHelperState newState);
public event NfcStatusMessageChangedHandler OnStatusMessageChanged;
}
before posting the question i did my research for 10 days so really hope someone can shed some light into solving this issue.
The issue is that any bindable control, does not update once the binding list from singleton class is changed. This is a common issue on multi-threaded apps. Most if not all solutions offer suggestions where the bindlinglist or collection is initialized from parent thread, and then some invocation to be made. Not what i'm looking for. The same issue persist if static class is used instead of singleton.
Basically, the application triggers some Tasks, which in turn create object(s) on different business classes. These objects post messages into the bindinglist, which should update the UI listbox, but does not. And yes, the message object is in the list, and binding after the TASK finished works (items displayed). Locking/unlocking object(s) access is also not an issue.
Appreciate any suggestions/solutions
A trimmed down version of business objects:
namespace MyNameSpace
{
public class Message
{
private string messageSummary;
public Message() { }
public string MessageSummary
{
set { messageSummary = value; }
get { return messageSummary; }
}
}
}
A trimmed down version of another class doing some ops:
namespace MyNameSpace
{
public class WorkDoingClass
{
public WorkDoingClass() { }
public void DoSomeWork()
{
//some routines
Message messageObj = new Message();
messageObj.MessageSummary = "DoSOmrWork Finished";
}
public void DoSomeOtherWork()
{
//some routines
Message messageObj = new Message();
messageObj.MessageSummary = "DoSomeOtherWork Finished";
AllMessages.Instance.AllMessagesBindingList.Add(messageObj);
}
}
}
Singleton:
namespace MyNameSpace
{
public sealed class AllMessages
{
private static readonly AllMessages _instance = new AllMessages();
private BindingList<Message> _allMessagesBL;
public WorkDoingClass() { _allMessagesBL = new BindingList<Message>(); }
public static AllMessages Instance
{
get { return _instance; }
}
public BindingList<Message> AllMessagesBindingList
{
get { return _allMessagesBL};
}
}
}
This is also a trimmed down version from where calls start:
namespace MyNameSpace
{
public partial class Form1 : Form
{
private Task _TaskSqlData;
private CancellationTokenSource cTokenSourceSql;
public Form1()
{
InitializeComponent();
listBox1.DataSource = AllMessages.Instance.AllMessagesBindingList;
listBox1.DisplayMember = "MessageSummary";
}
private void button1_Click(object sender, EventArgs e)
{
cTokenSourceSql = new CancellationTokenSource();
var tokenSqlData = cTokenSourceSql.Token;
if (this._TaskSqlData != null)
{
if (this._TaskSqlData.Status == TaskStatus.Running)
this.cTokenSourceSql.Cancel();
this._TaskSqlData.Dispose();
this._TaskSqlData = null;
}
_TaskSqlData = Task.Factory.StartNew(()
=> StartDoingWork(this, tokenSqlData, null), tokenSqlData);
}
public void StartDoingWork(object sender, CancellationToken ct, EventArgs e)
{
if (ct.IsCancellationRequested)
ct.ThrowIfCancellationRequested();
WorkDoingClass work = new WorkDoingClass();
work.DoSomeOtherWork();
}
Your problem is that the thread(the main UI thread) making the listbox is different from the thread(the worker thread) modifying the collection.
Try the following code. It could solve your issue. I use SynchronizationContext to synchronize the two threads, which serves as the same function with Control.Invoke().
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Task _TaskSqlData;
private CancellationTokenSource cTokenSourceSql;
WorkDoingClass _work;
public Form1()
{
InitializeComponent();
listBox1.DataSource = AllMessages.Instance.AllMessagesBindingList;
listBox1.DisplayMember = "MessageSummary";
_work = new WorkDoingClass(SynchronizationContext.Current);
}
private void button1_Click(object sender, EventArgs e)
{
cTokenSourceSql = new CancellationTokenSource();
var tokenSqlData = cTokenSourceSql.Token;
if (this._TaskSqlData != null)
{
if (this._TaskSqlData.Status == TaskStatus.Running)
this.cTokenSourceSql.Cancel();
this._TaskSqlData.Dispose();
this._TaskSqlData = null;
}
_TaskSqlData = Task.Factory.StartNew(()
=> StartDoingWork(this, tokenSqlData, null), tokenSqlData);
}
public void StartDoingWork(object sender, CancellationToken ct, EventArgs e)
{
if (ct.IsCancellationRequested)
ct.ThrowIfCancellationRequested();
_work.DoSomeOtherWork();
}
}
public class Message
{
private string messageSummary;
public Message() { }
public string MessageSummary
{
set { messageSummary = value; }
get { return messageSummary; }
}
}
public class WorkDoingClass
{
private SynchronizationContext _syncContext;
public WorkDoingClass() { }
public WorkDoingClass(SynchronizationContext _syncContext)
{
// TODO: Complete member initialization
this._syncContext = _syncContext;
}
public void DoSomeWork()
{
//some routines
Message messageObj = new Message();
messageObj.MessageSummary = "DoSOmrWork Finished";
}
public void DoSomeOtherWork()
{
_syncContext.Send(DoWork, null);
}
private static void DoWork(object arg)
{
//some routines
Message messageObj = new Message();
messageObj.MessageSummary = "DoSomeOtherWork Finished";
AllMessages.Instance.AllMessagesBindingList.Add(messageObj);
}
}
public sealed class AllMessages
{
private static readonly AllMessages _instance = new AllMessages();
private BindingList<Message> _allMessagesBL;
public AllMessages() { _allMessagesBL = new BindingList<Message>(); }
public static AllMessages Instance
{
get { return _instance; }
}
public BindingList<Message> AllMessagesBindingList
{
get { return _allMessagesBL; }
}
}
}