forked from Inumedia/SlackAPI
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSlackSocketClient.cs
148 lines (118 loc) · 3.89 KB
/
SlackSocketClient.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using SlackAPI.WebSocketMessages;
using System;
using System.Diagnostics;
using System.Threading;
namespace SlackAPI
{
public class SlackSocketClient : SlackClient
{
SlackSocket underlyingSocket;
public event Action<NewMessage> OnMessageReceived;
bool HelloReceived;
public const int PingInterval = 3000;
int pinging;
Timer pingingThread;
public long PingRoundTripMilliseconds { get; private set; }
public bool IsReady { get { return HelloReceived; } }
public bool IsConnected { get { return underlyingSocket != null && underlyingSocket.Connected; } }
public event Action OnHello;
internal LoginResponse loginDetails;
public SlackSocketClient(string token)
: base(token)
{
}
public SlackSocketClient(string token, string proxyAddress)
: base(token, proxyAddress)
{
}
public override void Connect(Action<LoginResponse> onConnected, Action onSocketConnected = null)
{
base.Connect((s) => {
onConnected(s);
ConnectSocket(onSocketConnected);
});
}
protected override void Connected(LoginResponse loginDetails)
{
this.loginDetails = loginDetails;
base.Connected(loginDetails);
}
public void ConnectSocket(Action onSocketConnected){
underlyingSocket = new SlackSocket(loginDetails, this, onSocketConnected);
}
public void BindCallback<K>(Action<K> callback)
{
underlyingSocket.BindCallback(callback);
}
public void UnbindCallback<K>(Action<K> callback)
{
underlyingSocket.UnbindCallback(callback);
}
public void SendPresence(Presence status)
{
underlyingSocket.Send(new PresenceChange() { presence = Presence.Active, user = base.MySelf.id });
}
public void SendTyping(string channelId)
{
underlyingSocket.Send(new Typing() { channel = channelId });
}
public void SendMessage(Action<MessageReceived> onSent, string channelId, string textData)
{
underlyingSocket.Send(new Message() { channel = channelId, text = textData, user = MySelf.id, type = "message" }, new Action<MessageReceived>((mr) => {
if(onSent != null)
onSent(mr);
}));
}
public void HandleHello(Hello hello)
{
HelloReceived = true;
StartPing();
if (OnHello != null)
OnHello();
}
public void HandlePresence(PresenceChange change)
{
UserLookup[change.user].presence = change.presence.ToString().ToLower();
}
void StartPing()
{
pingingThread = new Timer(Ping, null, PingInterval, PingInterval);
}
void Ping(object state)
{
if (Interlocked.CompareExchange(ref pinging, 1, 0) == 0)
{
//This isn't ideal.
//TODO: Setup a callback on the messages so I get a hit when the message is just being sent. Messages are currently handled async.
Stopwatch w = Stopwatch.StartNew();
underlyingSocket.Send(new Ping()
{
ping_interv_ms = PingInterval
}, new Action<Pong>((p) =>
{
w.Stop();
PingRoundTripMilliseconds = w.ElapsedMilliseconds;
pinging = 0;
}));
}
}
public void UserTyping(Typing t)
{
}
public void Message(NewMessage m)
{
if (OnMessageReceived != null)
OnMessageReceived(m);
}
public void PresenceChange(PresenceChange p)
{
}
public void ChannelMarked(ChannelMarked m)
{
}
public void CloseSocket()
{
underlyingSocket.Close();
}
}
}