How do I open a TCP socket from SilverLight? - silverlight

I need to know how to open a TCP socket connection from Silverlight. How is it done?

A quick google search delivers this site
Silverlight 2 and System.Net.Sockets.Socket

namespace SilverlightSocketClient
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
this.Loaded += PageLoaded;
}
void PageLoaded(object sender, RoutedEventArgs e)
{
var endPoint = new DnsEndPoint(Application.Current.Host.Source.DnsSafeHost, 4530);
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var args = new SocketAsyncEventArgs {UserToken = socket, RemoteEndPoint = endPoint};
args.Completed += OnSocketConnectCompleted;
socket.ConnectAsync(args);
}
private void OnSocketConnectCompleted(object sender, SocketAsyncEventArgs e)
{
var response = new byte[1024];
e.SetBuffer(response, 0, response.Length);
e.Completed -= OnSocketConnectCompleted;
e.Completed += OnSocketReceive;
var socket = (Socket)e.UserToken;
socket.ReceiveAsync(e);
}
private void OnSocketReceive(object sender, SocketAsyncEventArgs e)
{
StringReader sr = null;
try
{
string data = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
sr = new StringReader(data);
//Get data
if (data.Contains("Product"))
{
var xs = new XmlSerializer(typeof(Product));
var product = (Product) xs.Deserialize(sr);
Dispatcher.BeginInvoke(UpdateOrder);
}
//Get another type of data
if (data.Contains("Order"))
{
var xs = new XmlSerializer(typeof(Order));
var order = (Order)xs.Deserialize(sr);
var handler = new SomeEventHandler(UpdateOrder);
this.Dispatcher.BeginInvoke(handler, new object[]
{
order
});
}
}
catch (Exception ex)
{
//handle exception
}
finally
{
if (sr != null) sr.Close();
}
//Prepare to receive more data
var socket = (Socket)e.UserToken;
socket.ReceiveAsync(e);
}
}
}

Take a look at the Socket class in Silverlight. The MSDN documentation has a good sample.

Related

ServiceStack Exception handling in Silverlight

I am trying to understand how to handle an Exception in Silverlight that come from a ServiceStack service.
public class TestService : Service
{
public object Any (TestRequest request)
{
throw new Exception("Name");
var lst = new List<TestResponse>();
for (int i = 0; i < 20; i++)
{
var item = new TestResponse { ID = i, Descrizione = string.Format("Descr_{0}", i) };
lst.Add(item);
{
}
return lst;
}
}
}
I have seen in the wiki that the generic exception are handled as a 500 InternalServerError, but when i throw an Exception like in the example i do not receive the Exception data in the argument(but using fiddler i can see all the data in the Json).
My SilverLight code is
private ServiceClient<TestRequest, ContainerTestResponse> serviceClient;
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
serviceClient = new ServiceClient<TestRequest, ContainerTestResponse>();
serviceClient.Completed += serviceClient_Completed;
}
void serviceClient_Completed(object sender, ServiceClientEventArgs<ContainerTestResponse> e)
{
var webEx = e.Error as WebException;
if (webEx != null)
{
//can't figure out where "Name" is...
var webResponse = (HttpWebResponse)webEx.Response;
MessageBox.Show(webResponse.StatusDescription);
return;
}
if (e.Error != null)
throw e.Error;
var result = e.Response.Dati;
}
}
My JSon response is
{"ResponseStatus":{"ErrorCode":"Exception","Message":"Name","StackTrace":"[TestRequest: 19/11/2013 15:39:29]:\n[REQUEST: {}]\nSystem.Exception: Name\r\n at SSAuthenticationProvider.TestService.Any(TestRequest request) in c:\\projects\\2013\\Demo\\SSAuthenticationProvider\\SSAuthenticationProvider\\TestService.cs:line 20\r\n at ServiceStack.ServiceHost.ServiceRunner`1.Execute(IRequestContext requestContext, Object instance, TRequest request)","Errors":[]}}
Am I doing some mistake?
Thanks all

Async call of WCF using Duplex Communication to get Database change

I am implementing and WCF Async service using WsDualHttpBinding binding for duplex communication to get database changes.
I have implemented the Service but I dont know how to call it from Client application.
Here is the code.
The below code is WCF Service
[ServiceContract()]
public interface ICustomerService
{
[OperationContract(IsOneWay = true)]
void GetAllCustomer();
}
public interface ICustomerServiceCallback
{
[OperationContract(IsOneWay = true)]
void Callback(Customer[] customers);
}
[ServiceContract(Name = "ICustomerService",
CallbackContract = typeof(CustomerServiceLibrary.ICustomerServiceCallback),
SessionMode = SessionMode.Required)]
public interface ICustomerServiceAsync
{
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginGetAllCustomer(AsyncCallback callback, object asyncState);
void EndGetAllCustomer(IAsyncResult result);
}
[DataContract]
public class Customer
{
[DataMember]
public string Name
{
get;
set;
}
}
}
public class CustomerService :ICustomerService,IDisposable
{
List<Customer> Customers = null;
ICustomerServiceCallback callback;
Customer customer = null;
string constr = "Data Source=.;Initial Catalog=WPFCache;Persist Security Info=True;User ID=sa;Password=Password$2";
public CustomerService()
{
callback = OperationContext.Current.GetCallbackChannel<ICustomerServiceCallback>();
SqlDependency.Start(constr);
}
public void GetAllCustomer()
{
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand())
{
con.Open();
cmd.Connection = con;
cmd.CommandText = "GetHero";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Notification = null;
// Create the associated SqlDependency
SqlDependency dep = new SqlDependency(cmd);
dep.OnChange += new OnChangeEventHandler(dep_OnChange);
SqlDataReader dr = cmd.ExecuteReader();
Customers = new List<Customer>();
while (dr.Read())
{
customer = new Customer();
customer.Name = dr.GetString(0);
Customers.Add(customer);
}
}
callback.Callback(Customers.ToArray());
}
}
void dep_OnChange(object sender, SqlNotificationEventArgs e)
{
try
{
if (e.Type == SqlNotificationType.Change)
{
GetAllCustomer();
}
}
catch (Exception ex)
{
throw ex;
}
}
public void Dispose()
{
SqlDependency.Stop(constr);
}
}
I have hosted this WCF Async Service as self hosting in a Console Application.
Here the hosting code
class Program
{
static void Main(string[] args)
{
StartService();
}
internal static ServiceHost myServiceHost = null;
internal static void StartService()
{
Uri httpbaseAddress = new Uri("http://localhost:8087/CustomerService/");
Uri[] baseAdresses = { httpbaseAddress };
myServiceHost = new ServiceHost(typeof(CustomerServiceLibrary.CustomerService));
myServiceHost.AddServiceEndpoint(typeof(CustomerServiceLibrary.ICustomerService), new WSDualHttpBinding(), httpbaseAddress);
ServiceDescription serviceDesciption = myServiceHost.Description;
foreach (ServiceEndpoint endpoint in serviceDesciption.Endpoints)
{
Console.WriteLine("Endpoint - address: {0}", endpoint.Address);
Console.WriteLine(" - binding name:\t\t{0}", endpoint.Binding.Name);
Console.WriteLine(" - contract name:\t\t{0}", endpoint.Contract.Name);
Console.WriteLine();
}
myServiceHost.Open();
Console.WriteLine("Press enter to stop.");
Console.ReadKey();
if (myServiceHost.State != CommunicationState.Closed)
myServiceHost.Close();
}
}
In client Application have crated a DuplexChannel factory instance
Here is the Code.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
EndpointAddress address = new EndpointAddress(new Uri("http://localhost:8087/CustomerService"));
WSDualHttpBinding wsDualBinding = new WSDualHttpBinding();
DuplexChannelFactory<ICustomerServiceAsync> client = new DuplexChannelFactory<ICustomerServiceAsync>(new InstanceContext(this), wsDualBinding, address);
App.channel = client.CreateChannel();
}
Now My question is How I can call the
BeginGetAllCustomer
EndGetAllCustomer
Method of My service.
Help me.... A big thanks in Advance ...
You need:
InstanceContext instanceContext = new InstanceContext(YOUR_OBJECT_IMPLMENTS_CALLBACK);
and
using (App.channel as IDisposable)
{
App.channel.YOUR_METHOD_HERE();
}
from this example:
endPointAddr = "net.tcp://" + textBox2.Text + ":8000/FIXMarketDataHub";
NetTcpBinding tcpBinding = new NetTcpBinding();
tcpBinding.TransactionFlow = false;
tcpBinding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
tcpBinding.Security.Mode = SecurityMode.None;
EndpointAddress endpointAddress = new EndpointAddress(endPointAddr);
Append("Attempt to connect to: " + endPointAddr);
InstanceContext instanceContext = new InstanceContext(??);
IMarketDataPub proxy = DuplexChannelFactory<IMarketDataPub>.CreateChannel(instanceContext,tcpBinding, endpointAddress);
using (proxy as IDisposable)
{
proxy.Subscribe();
Append("Subscribing to market data");
}
See also microsoft example

HttpWebRequest in Silverlight

How to recreate the following code in Silverlight? I'm pretty lost when it comes to async.
public class StringGet
{
public static string GetPageAsString(Uri address)
{
string result = "";
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Read the whole contents and return as a string
result = reader.ReadToEnd();
}
return result;
}
public void DownloadHtml(Uri address){
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += WebClientDownloadString_Complete;
webClient.DownloadStringAsync(address)
}
private void WebClientDownloadString_Complete(object sender, DownloadStringCompletedEventArgs e) {
if (e.Error == null) {
string html = e.Result;
}
}

How do I update the UI from a HttpWebRequest?

In my Mainpage.xaml.cs file I have a function that creates an instance of another class and tries to download a webpage using a HttpWebRequest from that instance. The problem is, once I've managed to download the webpage I can't send it back to the main UI thread. I've tried using Deployment.Current.Dispatcher.BeginInvoke to send the webpage back to a TextBlock I have waiting, but when I try I get an error telling me that I can't access the TextBlock from the other class. Is there any way to pass data between two threads without using LocalStorage?
EDIT: code below:
MainPage:
private void button1_Click(object sender, RoutedEventArgs e)
{
Member m = new Member(name, id);
}
Member class:
public Member(String Member, String API)
{
APIKey = API;
MemberName = Member;
this.super = super;
DoSend(method, string, "", null);
}
public void DoSend(string method, string url, string body, string mimetype)
{
if (WebRequest.RegisterPrefix("https://",System.Net.Browser.WebRequestCreator.ClientHttp)) {
HttpWebRequest request = WebRequest.Create(makeURI(url)) as HttpWebRequest;
request.Method = method;
request.Headers["X-NFSN-Authentication"] = MakeAuthHeader(url,body);
if (body != "")
{
byte[] bodyData = Encoding.UTF8.GetBytes(body);
request.ContentType = mimetype;
//Stuff Should Happen Here
}
else
doStuff(request);
}
public void doStuff(HttpWebRequest httpReq)
{
httpReq.BeginGetResponse(r =>
{
var httpRequest = (HttpWebRequest)r.AsyncState;
var httpResponse = (HttpWebResponse)httpRequest.EndGetResponse(r);
using (var reader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = reader.ReadToEnd();
ResponseBlock.Text = response; //Invalid cross-thread reference
}
}, httpReq);
}
MainPage:
customClass.DownloadPage((result) =>
{
textBlock.Text = result;
},
(exception) =>
{
MessageBox.Show(exception.Message);
});
CustomClass:
public void DownloadPage(Action<string> callback, Action<Exception> exception)
{
WebClient webClient = new WebClient();
webClient.DonwloadStringCompleted += (s, e) =>
{
if (e.Error == null)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
callback(e.Result);
});
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
exception(e.Error);
});
}
};
webClient.DonwloadStringAsync();
}

Upload files with HTTPWebrequest from SilverLight application (Why does Content Length is 13?)

Friends!
Help me, please!
I try to post file from Silverlight. I use such class:
public class HttpHelper
{
public WebRequest Request { get; set; }
public Stream Filestream { get; private set; }
public HttpHelper(Stream filestream)
{
Request = WebRequest.Create("http://www.mysite.com/recieve");
Request.Method = "POST";
Request.ContentType = "application/octet-stream";
Filestream = filestream;
}
private static void BeginFilePostRequest(IAsyncResult ar)
{
HttpHelper helper = ar.AsyncState as HttpHelper;
if (helper != null)
{
byte[] bytes = new byte[helper.Filestream.Length];
int sf = helper.Filestream.Read(bytes, 0, (int)helper.Filestream.Length);
//helper.Request.ContentLength = bytes.Length; //It doesn't work in SL
using (StreamWriter writer = new StreamWriter(helper.Request.EndGetRequestStream(ar)))
{
writer.Write(bytes);
}
helper.Request.BeginGetResponse(new AsyncCallback(HttpHelper.BeginResponse), helper);
}
}
private static void BeginResponse(IAsyncResult ar)
{
HttpHelper helper = ar.AsyncState as HttpHelper;
if (helper != null)
{
HttpWebResponse response = (HttpWebResponse)helper.Request.EndGetResponse(ar);
if (response != null)
{
Stream stream = response.GetResponseStream();
if (stream != null)
{
using (StreamReader reader = new StreamReader(stream))
{
//anything...
}
}
}
}
}
public void PostFile()
{
this.Request.BeginGetRequestStream(new AsyncCallback(HttpHelper.BeginFilePostRequest), this);
}
}
I have Stream in my silverlight application and try to call PostFile by click submit button:
private void submit_button_Click(object sender, RoutedEventArgs e)
{
//...
HttpHelper helper = new HttpHelper(memory_stream);
helper.PostFile();
}
But mysite recieve request without file. It just has ContentLength 13. What's problem?
Try Flush on your writer before exiting the using block, you should also call Close on the stream retrieved from EndGetRequestStream.
you HAVE TO Flush and Dispose HTTP request stream and all downstream streams, then it works.

Resources