This example program subscribe on elog, sets-up a websocket connection and retrieve elog descriptions. Any inbound events received on the websocket is sent to a session thread using a simple message queue. Inbound elog events are deserialized by the session thread, the url to the elog resource is unpacked and then used when retrieving the elog message from the controller. The retrieved elog message contains an elog description in requested language. The printout contains both the elog event, received on the websocket and the elog description retrieved from the controller after the event has been unpacked.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using WebSocketSharp;
using System.Net;
using System.Xml;
namespace ElogSubscriber
{
class Program
{
public static string _host = "http://10.140.188.238";
public static string _userName = "Default User";
public static string _password = "robotics";
public static string _language = "?lang=en";
public static HttpWebCommunication _webcon = new HttpWebCommunication();
public static SimpleSafeList<string> messageQueue = new SimpleSafeList<string>();
static void Main(string[] args)
{
ControllerSession session = new ControllerSession();
Thread sessionThread = new Thread(new ThreadStart(session.Run));
sessionThread.Start();
Console.WriteLine("Hit ENTER to exit..."); Console.ReadLine();
messageQueue.Add("<info>exit");
sessionThread.Abort();
}
}
public class ControllerSession
{
public void Run()
{
string postData = "resources=1&1=" + "/rw/elog/0" + "&1-p=1";
HttpWebResponse response = Program._webcon.DoWebRequest("POST", Program._host + "/subscription", postData);
if (response.StatusCode != HttpStatusCode.Created)
{
Console.WriteLine("Error subscribe on resource {0} error {1}", postData, response.StatusCode.ToString());
return;
}
string location = response.Headers["Location"];
response.GetResponseStream().Close();
RWSWebSockets ws = new RWSWebSockets();
ws.WsConnect(Program.messageQueue, new Uri(Program._host), Program._webcon.GetAbbCookie(), Program._webcon.GetHttpSessionCookie());
string message = null;
do
{
message = Program.messageQueue.WaitRead();
if (message != null)
{
if (message.Substring(0, 6) == "<info>")
{
Console.WriteLine(message);
}
else if (message.Substring(0, 6) == "<data>")
{
string href = GetElogLink(message.Substring(6));
if (href != null)
{
string elogMsg = GetElogMessage(href);
if (elogMsg != null)
{
Console.WriteLine(elogMsg);
}
}
}
}
} while (true);
}
private string GetElogMessage(string elogUrl)
{
HttpWebResponse response = Program._webcon.DoWebRequest("GET", Program._host + elogUrl + Program._language, null);
if (response.StatusCode != HttpStatusCode.OK)
{
Console.WriteLine("Error get resource {0} error {1}", elogUrl, response.StatusCode.ToString());
return null;
}
string elogMessage = DeserializeElogResource(response.GetResponseStream());
response.GetResponseStream().Close();
return elogMessage;
}
string DeserializeElogResource(Stream elogXml)
{
string elogDescription = null;
string elogCode = null;
string elogTimeStamp = null;
XmlDocument doc = new XmlDocument();
doc.Load(elogXml);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ns", "http://www.w3.org/1999/xhtml");
XmlNodeList nodes = doc.SelectNodes("//ns:html/ns:body/ns:div/ns:ul/ns:li", nsmgr);
foreach (XmlNode node in nodes)
{
XmlAttribute type = node.Attributes["class"];
if (type != null)
{
string classType = type.Value.ToString();
switch (classType)
{
case "elog-message":
XmlNode elog = node.SelectSingleNode("//ns:span[@class='desc']", nsmgr);
if (elog != null)
{
elogDescription = elog.InnerText.ToString();
}
elog = node.SelectSingleNode("//ns:span[@class='code']", nsmgr);
if (elog != null)
{
elogCode = elog.InnerText.ToString();
}
elog = node.SelectSingleNode("//ns:span[@class='tstamp']", nsmgr);
if (elog != null)
{
elogTimeStamp = elog.InnerText.ToString();
}
break;
default:
break;
}
}
}
return elogCode + " " + elogTimeStamp + " " + elogDescription;
}
private string GetElogLink(string xmlResource)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlResource);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ns", "http://www.w3.org/1999/xhtml");
string elogHref = null;
string seqNo = null;
XmlNodeList nodes = doc.SelectNodes("//ns:html/ns:body/ns:div/ns:ul/ns:li", nsmgr);
foreach (XmlNode node in nodes)
{
XmlAttribute type = node.Attributes["class"];
if (type != null)
{
string classType = type.Value.ToString();
switch (classType)
{
case "elog-message-ev":
XmlNode elogNode = node.SelectSingleNode("ns:a[@rel='self']", nsmgr);
if (elogNode != null)
{
XmlAttribute rlink = elogNode.Attributes["href"];
elogHref = rlink.Value.ToString();
}
XmlNode elogSeqNo = node.SelectSingleNode("//ns:span[@class='seqnum']", nsmgr);
if (elogSeqNo != null)
{
seqNo = elogSeqNo.InnerText.ToString();
}
Console.WriteLine("Elog: seqNo={0} href={1}", seqNo, elogHref);
break;
default:
break;
}
}
}
return elogHref;
}
}
public class HttpWebCommunication
{
CookieContainer _cookies = new CookieContainer();
NetworkCredential _credentials = new NetworkCredential(Program._userName, Program._password);
Cookie _abbCookie = null;
Cookie _httpSessionCookie = null;
public HttpWebCommunication()
{
}
public HttpWebResponse DoWebRequest(string method, string url, string body)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url));
request.Credentials = _credentials;
request.Method = method;
request.CookieContainer = _cookies;
request.PreAuthenticate = true;
request.Proxy = null;
Uri uri = new Uri(url);
if (request.Method == "PUT" || request.Method == "POST")
{
request.ContentType = "application/x-www-form-urlencoded";
Stream s = request.GetRequestStream();
s.Write(Encoding.ASCII.GetBytes(body), 0, body.Length);
s.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (_abbCookie == null)
{
_abbCookie = GetAbbCookie(response);
}
if (_httpSessionCookie == null)
{
_httpSessionCookie = GetHttpSessionCookie(response);
}
return response;
}
private Cookie GetAbbCookie(HttpWebResponse response)
{
string abbcookiestr = null;
string cookiesText = (response as HttpWebResponse).Headers[HttpResponseHeader.SetCookie];
string[] lines = cookiesText.Split(';');
foreach (string line in lines)
{
string[] c = line.Split('=');
if (c[0] == "ABBCX" || c[0] == " httponly,ABBCX")
{
abbcookiestr = c[1];
break;
}
}
return new Cookie("ABBCX", abbcookiestr);
}
private Cookie GetHttpSessionCookie(HttpWebResponse response)
{
string httpcookiestr = null;
string cookiesText = (response as HttpWebResponse).Headers[HttpResponseHeader.SetCookie];
string[] lines = cookiesText.Split(';');
foreach (string line in lines)
{
string[] c = line.Split('=');
if (c[0] == "-http-session-")
{
httpcookiestr = c[1];
break;
}
}
return new Cookie("-http-session", httpcookiestr);
}
public Cookie GetAbbCookie()
{
return _abbCookie;
}
public Cookie GetHttpSessionCookie()
{
return _httpSessionCookie;
}
}
class RWSWebSockets
{
WebSocket websocket = null;
bool m_connected = false;
SimpleSafeList<string> m_messageQueue;
public void WsConnect(SimpleSafeList<string> msgQueue, Uri url, Cookie abbCookie, Cookie httpSessionCookie)
{
m_messageQueue = msgQueue;
string wsUrl = "ws://" + url.Authority + "/poll";
websocket = new WebSocket(wsUrl, "robapi2_subscription");
websocket.SetCookie(new WebSocketSharp.Net.Cookie(abbCookie.Name, abbCookie.Value));
websocket.SetCookie(new WebSocketSharp.Net.Cookie(httpSessionCookie.Name, httpSessionCookie.Value));
websocket.OnOpen += new EventHandler(WsOpened);
websocket.OnError += new EventHandler<WebSocketSharp.ErrorEventArgs>(WsError);
websocket.SetCredentials(Program._userName, Program._password, false);
websocket.OnMessage += new EventHandler<MessageEventArgs>(WsMessageReceived);
websocket.OnClose += new EventHandler<CloseEventArgs>(WsClosed);
websocket.Connect();
}
public void Close()
{
if (m_connected)
websocket.Close();
}
private void WsOpened(object sender, EventArgs e)
{
m_messageQueue.Add("<info>opened");
m_connected = true;
}
private void WsClosed(object sender, CloseEventArgs e)
{
m_messageQueue.Add("<info>closed");
m_connected = false;
}
private void WsError(object sender, WebSocketSharp.ErrorEventArgs e)
{
m_messageQueue.Add("<info>error");
}
private void WsMessageReceived(object sender, MessageEventArgs e)
{
m_messageQueue.Add("<data>" + e.Data.ToString());
}
}
public class SimpleSafeList<T>
{
private readonly List<T> _items = new List<T>();
private EventWaitHandle _ewh = new EventWaitHandle(false, EventResetMode.ManualReset);
private Int32 waitTime = 300;
public void Add(T item)
{
lock (this._items)
{
this._items.Add(item);
_ewh.Set();
}
}
public int Count
{
get
{
lock (this._items)
{
return this._items.Count;
}
}
}
public T this[int index]
{
get
{
lock (this._items)
{
return this._items[index];
}
}
}
public T WaitRead()
{
if (Count == 0)
{
_ewh.WaitOne(waitTime);
}
_ewh.Reset();
if (Count > 0)
{
T val = this[0];
this._items.Remove(val);
return val;
}
return default(T);
}
}
}