I'm trying to connect a client to a self-hosted SignalR-server.
My server looks like this:
static void Main(string[] args)
{
string url = "http://localhost:8081/";
var server = new Server(url);
server.MapConnection<MyConnection>("/echo");
server.Start();
Console.WriteLine("Server running on {0}", url);
Console.ReadKey();
}
public class MyConnection : PersistentConnection
{
}
It was the simplest I could came up with. And the client looks like this:
static void Main(string[] args)
{
SignalR.Client.Connection conn = new SignalR.Client.Connection("http://localhost:8081/echo");
Task start = conn.Start();
start.Wait();
if (start.Status == TaskStatus.RanToCompletion)
{
Console.WriteLine("Connected");
}
Console.ReadKey();
}
I can't get the code above to work. The server start, but when I run the client code to connect I got an error:
The remote server returned an error: (500) Internal Server Error.
And the server is also giving me an error: Cannot access a disposed object.
Have I forgot something? What am I doing wrong?
Edit:
The error I get on the server is the following....
SignalRtest.vshost.exe Error: 0 : A first chance exception of type 'System.AggregateException' occurred in mscorlib.dll
SignalR exception thrown by Task: System.AggregateException: One or more errors occurred. ---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.HttpListenerResponse'.
at System.Net.HttpListenerResponse.CheckDisposed()
at System.Net.HttpListenerResponse.get_OutputStream()
at SignalR.Hosting.Self.Infrastructure.ResponseExtensions.<>c_DisplayClass4.b_1(IAsyncResult ar)
at System.Threading.Tasks.TaskFactory.FromAsyncCoreLogic(IAsyncResult iar, Action1 endMethod, TaskCompletionSource1 tcs)
--- End of inner exception stack trace ---
---> (Inner Exception #0) System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.HttpListenerResponse'.
at System.Net.HttpListenerResponse.CheckDisposed()
at System.Net.HttpListenerResponse.get_OutputStream()
at SignalR.Hosting.Self.Infrastructure.ResponseExtensions.<>c_DisplayClass4.b_1(IAsyncResult ar)
at System.Threading.Tasks.TaskFactory.FromAsyncCoreLogic(IAsyncResult iar, Action1 endMethod, TaskCompletionSource1 tcs)<---
'client.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.DebuggerVisualizers\10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.DebuggerVisualizers.dll'
Looks like it's disposing the server variable because it doesn't see it being used later in the function. Add GC.KeepAlive( server ) to the end of your Main function to make sure it doesn't get disposed of early. Or better yet, but it in a using statement.
Related
When I try to PostAsync, no response is coming back, even though the content is coming through.
The connection closes after 20 seconds or so, giving me an exception.
I'm getting a 200 OK, when Posting in Postman.
This is the code calling the method with .Wait:
StringContent sc = new StringContent(xml, Encoding.UTF8, "application/xml");
var t = Task.Factory.StartNew(() => MyAsyncMethod(sc, ao.orderId).Wait());
t.Wait();
t.Dispose();
This is the method:
public async Task MyAsyncMethod(StringContent sc, string orderid)
{
try
{
var response = await client.PostAsync("www.url.com", sc);
}
catch (Exception e)
{
using (StreamWriter writer = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "/Log/PostException.txt"))
{
writer.WriteLine(e.Message);
}
}
}
The Exception:
An error occurred while sending the request. at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at ShipNoticeInvoiceAPI.BLL.ShipNoticeGenerator.<SendShipNotice>d__4.MoveNext()
System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly. at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
System.Collections.ListDictionaryInternal
-2146233088
mscorlib
Void ThrowForNonSuccess(System.Threading.Tasks.Task)
I hope that you have tried something simular and are able to help me out. I feel like I've tried everything.
I used HttpWebRequest to async call a web service, occasionally EndGetResponse() returns some exceptions. However, even I got the exception, the call is successful and the data are returned. The following is my code with error checking code removed. I got 4 log items and the order is like this:
The following result is returned: ...
GetResult is successful!
PostXML exception: ...
GetResult exception: ...
public async Task<string> GetResult(string xmlData)
{
try
{
string response = await PostXML(Url, xmlData).ConfigureAwait(false);
_logger.Log($"GetResult is successful!");
return response;
}
catch (Exception ex)
{
_logger.Log("GetResult exception: " + ex.ToString());
throw;
}
}
private async Task<string> PostXML(string destinationUrl, string requestXml)
{
try
{
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(requestXml);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl);
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)await Task.Factory
.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
if (response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
string responseStr = new StreamReader(responseStream).ReadToEnd();
_logger.Log("The following result is returned: \r\n" + responseStr);
responseStream.Close();
return responseStr;
}
}
catch (Exception ex)
{
_logger.Log("PostXML exception: " + ex.ToString());
throw;
}
return null;
}
The exception is like this:
PostXML() exception: System.Net.WebException: The underlying connection was closed: A connection that was expected to be kept alive was closed by the server.
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MyService.d__7.MoveNext()
I guess I haven't fully understood how HttpWebRequest works in async mode. Anyway I hope these questions can help me to understand it more:
1. Why does the execution continue even an exception occurs? In my understanding, there should only have 2 log items to log the exception.
2. What is the reason the exception "The underlying connection was closed" occurs? Why does the exception occur but the service still gave back the correct result?
Why does the execution continue even an exception occurs? In my understanding, there should only have 2 log items to log the exception.
This isn't possible. I suspect your code is calling GetResult twice. That's what the log seems to indicate.
What is the reason the exception "The underlying connection was closed" occurs?
This happens when the server closes the connection before the client is ready for it to be closed. This is an unusual error to get from a REST API, but not unheard of.
I've been trying to send a XML file from my WCF to my project without much luck. I have a Exception thrown from my program once the response is completed by WCF and sent to the Phone. I was hoping someone could please help me, as I have been looking around for an answer and found nothing. (The program uses XNA for a Windows Phone Applications)
[System.Net.WebException] {System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.<EndGetResponse>b__d(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)
--- End of inner exception stack trace ---
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)} System.Net.WebException
public string EndHighScoreList(System.IAsyncResult result) {
object[] _args = new object[0];
string _result = ((string)(base.EndInvoke("HighScoreList", _args, result)));
return _result;
}
IService.cs
[ServiceContract]
[XmlSerializerFormat]
public interface IService
{
[OperationContract]
void ParseScore(HighScore score);
[OperationContract]
string HighScoreList();
}
public class HighScore
{
[XmlElement]
public UInt32 m_rank;
[XmlAttribute]
public string m_name;
[XmlAttribute]
public UInt32 m_score;
}
Service.svc
public string HighScoreList()
{
XmlSerializer ser = new XmlSerializer(typeof(HighScore));
using (FileStream fs = new FileStream(HttpContext.Current.Server.MapPath("App_Data/Highscores.xml"), FileMode.OpenOrCreate))
{
return ser.Deserialize(fs).ToString();
}
}
Here's the requested code
void globalRecieve(object obj, DodgeService.HighScoreListCompletedEventArgs e)
{
try
{
string result = e.Result;
using (TextReader reader = new StringReader(result)){
XmlSerializer xml = new XmlSerializer(typeof(List<DodgeService.HighScore>));
foreach (DodgeService.HighScore sco in xml.Deserialize(reader) as List<DodgeService.HighScore>)
highScores.Add(sco);
}
}catch(Exception exception){
string error = exception.Message;
}
}
protected override void Initialize()
{
service = new DodgeService.ServiceClient("BasicHttpBinding_IService");
service.HighScoreListAsync(null);
service.HighScoreListCompleted += new EventHandler<DodgeService.HighScoreListCompletedEventArgs>(globalRecieve);
base.Initialize();
}
Personally I believe WCF sucks. The Configuration alone is a nightmare and if you change anything, you have to re-build your objects and any changes you've made you have to re-make.
You should migrate to ServiceStack. It handles everything for you. You only write the sending and receiving of business DTO objects. Sending and receiving files is basic stuff for it,
See this google search for several people asking similar questions but based on ServiceStack. Mythz is a project lead for ServiceStack and he answers their questions. It should get you started and you should see how EASY it is.
Just for future reference in case that google search doesn't give the same as I got, here is the search and first three responses;
"servicestack file upload"
Using ServiceStack to upload image files
How to use Servicestack PostFileWithRequest
ServiceStack client add attachment
The error says: "NotFound". It looks like the operation HighScoreList is not exposed / available at all. Try opening the path in your browser.
I kept having a Not Found error because, then the Windows Phone ran it was trying to connect to the service via LocalHost which wouldn't work as I needed it to connect to the development PC. The solution was to host the WCF service on a server and connect to the server or connect to the IP of the development PC.
I work on a project target Windows Phone 7.5 and above.
I use a method to get online image and check the type of the image, if it is gif then I will coonvert it into jpg and bind it to a image control, if jpg and png, just bind with no encoding.
But codes below throws a error very frequently, "The remote server returned an error: NotFound",why? I have already catch the WebException.
public void GetOnlineImageAndReturnJPGStream(Action<Stream, string> callback, string uriString)
{
string errorstring = "";
try
{
WebClient wc = new WebClient();
wc.Headers[HttpRequestHeader.Referer] = "http://www.xici.net";
wc.AllowReadStreamBuffering = true;
wc.OpenReadCompleted += (s, e) =>
{
if (e.Error == null && !e.Cancelled)
{
//check pic type
ImageTypeCheck.ImageType incomingIMGType = ImageTypeCheck.getImageType(e.Result);
switch (incomingIMGType)
{
case ImageTypeCheck.ImageType.Gif://if gif
//deal with gif
case ImageTypeCheck.ImageType.Null:
case ImageTypeCheck.ImageType.Bmp:
//deal with bmp
case ImageTypeCheck.ImageType.Jpg:
case ImageTypeCheck.ImageType.Png:
//deal with jpg and png
}
}
else
{
errorstring = e.Error.Message;
callback(e.Result, errorstring);
}
};
wc.OpenReadAsync(new Uri(uriString, UriKind.Absolute));
}
catch (WebException webEx)
{
App.ShowToastNotification(webEx.Message);
}
}
The unhandle exception is below:
{System.Net.WebException: The remote server returned an error:
NotFound. ---> System.Net.WebException: The remote server returned an
error: NotFound. at
System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult
asyncResult) at
System.Net.Browser.ClientHttpWebRequest.<>c_DisplayClasse.b_d(Object
sendState) at
System.Net.Browser.AsyncHelper.<>c_DisplayClass1.b_0(Object
sendState) --- End of inner exception stack trace --- at
System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at System.Net.OpenReadCompletedEventArgs.get_Result() at
xicihutong.DataServiceAgent.ServiceAgent.<>c_DisplayClassa.b_8(Object
s, OpenReadCompletedEventArgs e) at
System.Net.WebClient.OnOpenReadCompleted(OpenReadCompletedEventArgs e)
at System.Net.WebClient.OpenReadOperationCompleted(Object arg)}
[System.Net.WebException]: {System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The
remote server returned an error: NotFound. at
System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult
asyncResult) at
System.Net.Browser.ClientHttpWebRequest.<>c_DisplayClasse.b_d(Object
sendState) at
System.Net.Browser.AsyncHelper.<>c_DisplayClass1.b_0(Object
sendState) --- End of inner exception stack trace --- at
System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at System.Net.OpenReadCompletedEventArgs.get_Result() at
xicihutong.DataServiceAgent.ServiceAgent.<>c_DisplayClassa.b_8(Object
s, OpenReadCompletedEventArgs e) at
System.Net.WebClient.OnOpenReadCompleted(OpenReadCompletedEventArgs e)
at System.Net.WebClient.OpenReadOperationCompleted(Object arg)}
_className: "System.Net.WebException"
_data: null
_dynamicMethods: null
_exceptionMethod: null
_exceptionMethodString: null
_helpURL: null
_HResult: -2146233079
innerException: {System.Net.WebException: The remote server returned an error: NotFound. at
System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult
asyncResult) at
System.Net.Browser.ClientHttpWebRequest.<>c_DisplayClasse.b_d(Object
sendState) at
System.Net.Browser.AsyncHelper.<>c_DisplayClass1.b__0(Object
sendState)}
_ipForWatsonBuckets: 0
_message: "The remote server returned an error: NotFound."
_remoteStackIndex: 0
_remoteStackTraceString: null
_source: null
_stackTrace: {sbyte[96]}
_stackTraceString: null
_watsonBuckets: {byte[5616]}
_xcode: -532462766
xptrs: 0
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2146233079
InnerException: {System.Net.WebException: The remote server returned an error: NotFound. at
System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult
asyncResult) at
System.Net.Browser.ClientHttpWebRequest.<>c_DisplayClasse.b_d(Object
sendState) at
System.Net.Browser.AsyncHelper.<>c_DisplayClass1.b__0(Object
sendState)}
IPForWatsonBuckets: 0
Message: "The remote server returned an error: NotFound."
RemoteStackTrace: null
Source: "System"
StackTrace: " at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()\r\n
at System.Net.OpenReadCompletedEventArgs.get_Result()\r\n at
xicihutong.DataServiceAgent.ServiceAgent.<>c_DisplayClassa.b_8(Object
s, OpenReadCompletedEventArgs e)\r\n at
System.Net.WebClient.OnOpenReadCompleted(OpenReadCompletedEventArgs
e)\r\n at System.Net.WebClient.OpenReadOperationCompleted(Object
arg)"
WatsonBuckets: {byte[5616]}
Why? and how to handle it?
unfortunately the error message I post is a Unhandle Exception and told me that our server returns a error, but I thought that I've already catch the 404 error in the Unhandle exception, Why does it throw it anyway?
To get more details about the reason of an exception, check the Status property of the WebException object. Also it can be a certificate problem if your app sends an https request.
You can't catch exception in described way because it is raised asynchronously in OpenReadCompleted event handler when you access Result property. In case an error has occurred you can't get a Result so an exception is raised. To handle it put try catch block inside the event handler, but actually to prevent an exception just don't pass a Result to callback in case an error has occurred.
debug it and try opening the full address of the image you are downloading in the browser. Maybe there's a missing slash or something in the url.
This is yet again a problem I have with saving images in silverlight to my database, I thought I had it all working untill I tried it out with a different image...
I save images to my database with following method.
I first convert the image to an array of byte and then send it to my service.
private void btnUpload_Click(object sender, RoutedEventArgs e)
{
//nieuwe instantie van de klasse "Afbeelding", om later door te sturen naar service
Afbeelding a = new Afbeelding();
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "JPEG files|*.jpg";
if (openFileDialog.ShowDialog() == true)
{
//Afbeelding ophalen via open dialoog
Stream stream = (Stream)openFileDialog.File.OpenRead();
string fileName = openFileDialog.File.Name;
//Converteren naar bytes
//byte[] bytes = BinaryConverter.convertToByte(stream);
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
//aan de instantie de Binary waarde van de afbeelding meegeven om naar de database te sturen
a.id = 1;
a.source = new Binary { Bytes = bytes };
}
EditAfbeeldingServiceClient client = new EditAfbeeldingServiceClient();
client.UpdateAfbeeldingCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_UpdateAfbeeldingCompleted);
client.UpdateAfbeeldingAsync(a);
}
And in my service I do this:
[OperationContract]
public void UpdateAfbeelding(Afbeelding a)
{
var query = (from p in dc.Afbeeldings
where p.id == a.id
select p).SingleOrDefault();
query.source = a.source;
dc.SubmitChanges();
}
Now during my testing this all worked, but I only used one image to test...
So when I tried just now with a different image, I get the following error:
System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (400) Bad Request. In Silverlight, a 404 response code may be reported even when the service sends a different error code. ---> System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass4.<BeginOnUI>b__0(Object sendState)
--- End of inner exception stack trace ---
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
--- End of inner exception stack trace ---
at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at OndernemersAward.EditAfbeeldingServiceReference.EditAfbeeldingServiceClient.EditAfbeeldingServiceClientChannel.EndUpdateAfbeelding(IAsyncResult result)
at OndernemersAward.EditAfbeeldingServiceReference.EditAfbeeldingServiceClient.OndernemersAward.EditAfbeeldingServiceReference.EditAfbeeldingService.EndUpdateAfbeelding(IAsyncResult result)
at OndernemersAward.EditAfbeeldingServiceReference.EditAfbeeldingServiceClient.OnEndUpdateAfbeelding(IAsyncResult result)
at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)
I can't really read anything out of that error so once again, I'm stuck here.
I apologise for using these boards so much, but I really wouldn't if it wasn't needed so much.
I have set the maximum to send through to a high number, but it still doesn't work.
<readerQuotas maxDepth="32"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
You can find my web.config here: http://pastebin.com/whMs5h1w
Thank you for your help, I really appreciate it.
Thomas
Edit: I managed to get a more readable error with enabling tracing, hope this helps anyone :)
WCF has various limits built in. One is the maxReceivedMessageSize which is 65536 bytes by default and another one is maxArrayLength (not sure what the default is). There is a good chance you have exceeded one of the two (or both). You can change those in your service configuration. This article on MSDN contains some example configurations.
Also enabling tracing for your service might provide you with some more insight of which limits are hit.
Btw: There is a File.ReadAllBytes method.
Edit: Apparently there is a tool called Fiddler which can help tracking these issues down.