Open dazxa opened 10 years ago
Hello there,
Would you show me WebSocket part of your apps code? (The above logs seem like that a data was sent after the WebSocket closing.)
Hi there,
Abridged code is below.
Many thanks
Darryl
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Configuration;
using WebSocketSharp;
namespace WebSocketProxyService
{
public partial class WebSocketProxy : ServiceBase
{
public WebSocketProxy()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("WebSocketProxyService"))
{
System.Diagnostics.EventLog.CreateEventSource("WebSocketProxyService", "WebSocketProxyServiceLog");
}
eventLog1.Source = "WebSocketProxyService";
eventLog1.Log = "WebSocketProxyServiceLog";
}
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("WebSocketProxyService On Start", EventLogEntryType.Information);
MetServiceMessageHandler messageHandler = null;
try
{
messageHandler = new MetServiceMessageHandler(eventLog1);
}
catch (Exception e1)
{
eventLog1.WriteEntry("Error: " + e1.Message, EventLogEntryType.Error);
}
string serviceWebSocketAddress = string.Empty;
try
{
serviceWebSocketAddress = ConfigurationManager.AppSettings["ServiceWebSocketAddress"];
}
catch (Exception e2)
{
eventLog1.WriteEntry("Error: " + e2.Message, EventLogEntryType.Error);
}
try
{
eventLog1.WriteEntry(serviceWebSocketAddress);
using(var ws = new WebSocket(serviceWebSocketAddress))
{
ws.Log.File = "C:/logs/log.txt";
ws.Log.Level = LogLevel.Debug;
eventLog1.WriteEntry("Log Level:" + ws.Log.Level);
eventLog1.WriteEntry("File:" + ws.Log.File);
ws.OnOpen += (sender, e) =>
{
eventLog1.WriteEntry("Opened New Connection");
};
ws.OnClose += (sender, e) =>
{
eventLog1.WriteEntry(String.Format("Closed Connection, Code: {0} \n Reason: {1}: \n Raw: {2} Sender: {3}", e.Code, e.Reason, e.ToString(), sender.ToString()));
};
ws.OnMessage += (sender, e) =>
{
eventLog1.WriteEntry("Message");
messageHandler.HandleMessage(e.Data, ws);
};
eventLog1.WriteEntry("Begin Connect");
ws.Connect();
eventLog1.WriteEntry("End Connect");
}
}
catch (Exception ex)
{
eventLog1.WriteEntry(String.Format("Error Connection, Msg: {0} \n Inner Exception: {1}\n Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace), EventLogEntryType.Error);
}
}
protected override void OnStop()
{
eventLog1.WriteEntry("WebSocketProxyService Entering On Stop");
}
private void eventLog1_EntryWritten(object sender, EntryWrittenEventArgs e)
{
}
}
}
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using WebSocketProxyService.EsriData;
using WebSocketSharp;
using WebSocketSharp.Server;
namespace WebSocketProxyService
{
public interface IMessageHandler
{
void HandleMessage(string data, WebSocket ws);
}
public class ServiceMessageHandler : IMessageHandler
{
private WebSocketServer wsss;
private EventLog messageHandlerLogger;
public ServiceMessageHandler(EventLog logger)
{
try
{
messageHandlerLogger = logger;
string url = ConfigurationManager.AppSettings["WebSocketHostUrl"];
wsss = new WebSocketServer(url);
wsss.AddWebSocketService<Broadcaster>("/MyEndPoint");
wsss.Start();
}
catch (Exception e)
{
logger.WriteEntry("Error: " + e.Message, EventLogEntryType.Error);
}
}
public void HandleMessage(string data, WebSocketSharp.WebSocket ws)
{
try
{
JObject msg = JsonConvert.DeserializeObject(data) as JObject;
this.messageHandlerLogger.WriteEntry("Msg Recieved:" + data, EventLogEntryType.Information);
string msgType = msg.Value<String>("type");
if (msgType == "401")
{
serviceAuthDoc ServiceAuthDoc = new ServiceAuthDoc();
serviceAuthDoc.user = ConfigurationManager.AppSettings["ServiceAuthDocUser"];
serviceAuthDoc.product = ConfigurationManager.AppSettings["ServiceAuthDocProduct"];
Document document = new Document();
long timeout;
long.TryParse(ConfigurationManager.AppSettings["ServiceAuthDocTimeout"], out timeout);
document.timeout = timeout;
serviceAuthDoc.document = JsonConvert.SerializeObject(document);
serviceAuthDoc.expiryDate = ConfigurationManager.AppSettings["ServiceAuthDocExpiryDate"];
serviceAuthDoc.signature = ConfigurationManager.AppSettings["ServiceAuthDocSignature"];
string authDoc = JsonConvert.SerializeObject(serviceAuthDoc);
MyData myData = new MyData();
myData.type = "auth";
myData.data = authDoc;
string returnMsg = JsonConvert.SerializeObject(metData);
this.messageHandlerLogger.WriteEntry("Pre Send With Msg:" + returnMsg, EventLogEntryType.Information);
ws.Send(returnMsg);
}
else if (msgType == "auth")
{
this.messageHandlerLogger.WriteEntry("Auth: " + msg.Value<String>("data"), EventLogEntryType.Information);
}
else if (msgType == "servicemsg")
{
this.messageHandlerLogger.WriteEntry("Service msg: " + msg.Value<String>("data"), EventLogEntryType.Information);
wsss.WebSocketServices.Broadcast(msg.ToString());
}
else if (msgType == "status")
{
this.messageHandlerLogger.WriteEntry("Status msg: " + msg.Value<String>("data"), EventLogEntryType.Information);
}
else if (msgType == "error")
{
this.messageHandlerLogger.WriteEntry("Error: " + msg.Value<String>("data"), EventLogEntryType.Error);
}
else
{
this.messageHandlerLogger.WriteEntry("Error: " + msg.Value<String>("data"), EventLogEntryType.Error);
}
}
catch (Exception e)
{
this.messageHandlerLogger.WriteEntry("Error: " + e.Message, EventLogEntryType.Error);
}
}
}
public class Broadcaster : WebSocketService
{
public EventLog messageHandlerLogger;
protected override void OnOpen()
{
base.OnOpen();
}
protected override void OnClose(CloseEventArgs e)
{
base.OnClose(e);
}
protected override void OnError(WebSocketSharp.ErrorEventArgs e)
{
base.OnError(e);
}
protected override void OnMessage(MessageEventArgs e)
{
}
}
}
Hi there,
As I was using a "using" statement above, the services container was calling Dispose as this implements iDisposable. See above code.
As a fix I am going to remove the using statement to allow the web socket to be deployed using windows services.
Any comments or suggestions welcomed.
Best Regards
Darryl
@dazxa Thanks for input.
namespace WebSocketProxyService
{
public partial class WebSocketProxy : ServiceBase
{
...
private WebSocket ws;
protected override void OnStart(string[] args)
{
...
try
{
// Remove using statement.
ws = new WebSocket(serviceWebSocketAddress);
...
ws.Connect();
eventLog1.WriteEntry("End Connect");
}
catch (Exception ex)
{
...
}
}
protected override void OnStop()
{
eventLog1.WriteEntry("WebSocketProxyService Entering On Stop");
if (ws != null && ws.ReadyState == WebSocketState.Open)
ws.Close();
}
...
}
}
I think you should remove using
statement, too.
So, have you still got same error?
Hi there,
Removing the "using" statement fixes the issue.
I will call dispose() explicitly on stop.
Many thanks
Darryl
Hi there, I've created a application using web socket sharp. This works fine when running as a console app, however when deployed as a windows service (As Admin) it fails on send. Debugging info below. Any ideas why this is would be most welcomed. Many thanks Darryl
4/07/2014 3:14:46 p.m.|Debug|WebSocket.send:0|A WebSocket connection request to wss://url:443/websocket/v2: GET /websocket/v2 HTTP/1.1 User-Agent: websocket-sharp/1.0 Upgrade: websocket Connection: Upgrade Host: url:443 Sec-WebSocket-Key: pFtLpPPxJ5WBJ/G8BR5A+Q== Sec-WebSocket-Protocol: wss Sec-WebSocket-Version: 13 4/07/2014 3:14:46 p.m.|Debug|WebSocket.receiveHandshakeResponse:0|A response to this WebSocket connection request: HTTP/1.1 101 Switching Protocols Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Accept: kOyOtZ3xHDrgox+kybKdkG3wMZA= Sec-WebSocket-Protocol: wss 4/07/2014 3:14:46 p.m.|Error|WebSocket.Send:0|While closing the WebSocket connection. 4/07/2014 3:14:46 p.m.|Info |WebSocket.close:0|Closing the WebSocket connection has already been done. 4/07/2014 3:14:46 p.m.|Debug|WebSocket.closeHandshake:0|Was clean?: True sent: True received: True