private async Task ConnectToServer()
{
string uri = "http://<My Server IP>:8082";
string token = "<My Token>";
try
{
HttpClient client = new HttpClient();
var response1 = await client.GetAsync($"http://{uri}/api/session?token={token}");
var response2 = await client.GetAsync($"http://{uri}/api/devices");
var json = await response2.Content.ReadAsStringAsync();
var devices = JsonConvert.DeserializeObject<List<Device>>(json);
Dictionary<string, IEnumerable<string>> headers = null;
headers = response1.Headers.ToDictionary(a => a.Key, a => a.Value);
var datat = headers.Values.Where(m => m.FirstOrDefault().Contains("JSESSION")).FirstOrDefault().FirstOrDefault();
var split_response = datat.Split(";");
var response_fromsplit = split_response[0].Split("=");
Uri myUri = new Uri($"ws://{uri}/api/socket");
ClientWebSocket socket = new ClientWebSocket();
socket .SetCookie(new ClientWebSocket.Net.Cookie { Name= "JSESSIONID", Value = response_fromsplit[1] });
// Here is where my knowledge is lacking...
// I don't know how to "send the authentication cookie"...
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
public class Device
{
public int Id { get; set; }
public string Name { get; set; }
public string UniqueId { get; set; }
// Other fields as needed...
}
I just started to make my first steps with sockets. I use this Code, its working well in Xamarin Forms and ASP.NET Core :
private async void Sockets_Start()
{
string sessionid = GetSessionId();
if (sessionid == "") return;
ClientWebSocket socket = new ClientWebSocket();
socket.Options.Cookies = new System.Net.CookieContainer();
socket.Options.Cookies.Add(new Uri(SocketServer()), new System.Net.Cookie("JSESSIONID", sessionid));
await socket.ConnectAsync(new Uri(SocketServer()), System.Threading.CancellationToken.None);
if (socket.State != WebSocketState.Open) return;
WebSocketReceiveResult result;
var buffer = new byte[65536];
do
{
result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
string json = Encoding.UTF8.GetString(buffer, 0, result.Count);
Socket soc = JsonConvert.DeserializeObject<Socket>(json);
if (soc.devices != null) foreach (var dev in soc.devices) Socket_Device(dev);
if (soc.positions != null) foreach (Position pos in soc.positions) Socket_Position(pos);
if (soc.events != null) foreach (Event ev in soc.events) Socket_Event(ev);
}
while (!result.CloseStatus.HasValue);
await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
If you don't know how to get the SessionID let me know.
#Bernd
New code :
private void Sockets_Start()
{
Thread thread = new Thread(SocketsStartAsync);
thread.Start();
}
private async void SocketsStartAsync() // #sockets
{
string sessionid = new clsTraccarApi().GetSessionId();
if (sessionid == "")
{
Error("No connection to traccar server !");
return;
}
ClientWebSocket socket = new ClientWebSocket();
socket.Options.Cookies = new System.Net.CookieContainer();
socket.Options.Cookies.Add(new Uri(com.SocketServer()), new System.Net.Cookie("JSESSIONID", sessionid));
await socket.ConnectAsync(new Uri(com.SocketServer()), System.Threading.CancellationToken.None);
if (socket.State != WebSocketState.Open) return;
_socket_close = false;
WebSocketReceiveResult result;
var buffer = new byte[128 * 1024];
while (!_socket_close)
{
result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
string json = Encoding.UTF8.GetString(buffer, 0, result.Count);
if (!json.EndsWith("}]}"))
{
Thread.Sleep(100);
result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
json += Encoding.UTF8.GetString(buffer, 0, result.Count);
}
json = api.ConvertJson(json);
Socket soc = JsonConvert.DeserializeObject<Socket>(json);
if (soc.devices != null) for (int i = 0; i < soc.devices.Count; i++) Socket_Device(soc.devices[i]);
if (soc.positions != null) for (int i = 0; i < soc.positions.Count; i++) Socket_Position(soc.positions[i]);
if (soc.events != null) for (int i = 0; i < soc.events.Count; i++) Socket_Event(soc.events[i]);
}
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Good Bye", CancellationToken.None);
}
@BerndFfm Can you help me with the code for api.convertJson and definition for soc device, position and events class. Thanks
json = api.ConvertJson(json);
Socket soc = JsonConvert.DeserializeObject<Socket>(json);
if (soc.devices != null) for (int i = 0; i < soc.devices.Count; i++) Socket_Device(soc.devices[i]);
if (soc.positions != null) for (int i = 0; i < soc.positions.Count; i++) Socket_Position(soc.positions[i]);
if (soc.events != null) for (int i = 0; i < soc.events.Count; i++) Socket_Event(soc.events[i]);
I'm attempting to create a C# WPF app that (in part) connects to the Traccar Websockets API and receives the positions of my devices real-time. I'm essentially trying to mimic what the "Simple Web" example does here (https://github.com/traccar/traccar-web/blob/master/web/simple/app.js) where my app connects to the server, gets the list of devices, and then listens for the real-time feed from the server. I've been able to get to the point where I can retrieve the list of devices, but then I need to connect to the Websocket API (/api/socket) and I'm essentially clueless on how to do that. As stated in the documentation (https://www.traccar.org/traccar-api/) it says that "Session cookie is the only authorization option for WebSocket connection", and in a post here (https://www.traccar.org/forums/topic/use-websocket-in-traccaar-server/) Anton mentions that "You need to pass authentication cookie in the header when you open socket." Similar info in this post... (https://www.traccar.org/forums/topic/connecting-to-websockets-using-session-cookies/) Unfortunately I don't really know how to do that in C# (or really any language), so curious to know if someone would have an idea of how to do this...(with specific C# code...) Here is what I have so far...
private async Task ConnectToServer() { string uri = "http://<My Server IP>:8082"; string token = "<My Token>"; try { HttpClient client = new HttpClient(); var response1 = await client.GetAsync($"http://{uri}/api/session?token={token}"); var response2 = await client.GetAsync($"http://{uri}/api/devices"); var json = await response2.Content.ReadAsStringAsync(); var devices = JsonConvert.DeserializeObject<List<Device>>(json); Uri myUri = new Uri($"ws://{uri}/api/socket"); ClientWebSocket socket = new ClientWebSocket(); // Here is where my knowledge is lacking... // I don't know how to "send the authentication cookie"... } catch (Exception ex) { Console.WriteLine(ex); } } public class Device { public int Id { get; set; } public string Name { get; set; } public string UniqueId { get; set; } // Other fields as needed... }