Sub Process_Globals
Private sock As Socket
Private astream As AsyncStreams
Private bc As ByteConverter
Private timer1 As Timer
Type Message(Text As String, Sound As Boolean, Badge As Int, ExpirationDate As Long, HighPriority As Boolean, Title As String)
Private queue As List
Private queueTimer As Timer
Type IOS_DeviceAndMessage(Device As String, Msg As Message)
Private connected As Boolean
Private const NUMBER_OF_TOKENS_PER_REQUEST As Int = 5
End Sub
Public Sub Start
bc.LittleEndian = False
queue.Initialize
queueTimer.Initialize("queueTimer", 500)
timer1.Initialize("timer1", 3000) 'this timer is used when trying to reconnect
Connect
End Sub
Private Sub Connect
If sock.IsInitialized Then sock.Close
Dim sock As Socket
sock.InitializeSSL("sock", File.OpenInput(Yodfat.config.Get("iPushKeystore"), ""), Yodfat.config.Get("iPushKeystorePassword"))
sock.Connect(Yodfat.config.Get("iGateway"), Yodfat.config.Get("iGateWayPort"), 30000)
End Sub
Private Sub sock_Connected (Successful As Boolean)
If Successful Then
timer1.Enabled = False
Log("Socket connected.")
Dim jo As JavaObject = sock
jo.GetFieldJO("socket").RunMethod("setTcpNoDelay", Array(True))
If astream.IsInitialized Then astream.Close
astream.Initialize(sock.InputStream, sock.OutputStream, "astream")
connected = True
queueTimer.Enabled = True
Else
Log("Error connecting socket: " & LastException)
Reconnect
End If
End Sub
Private Sub Reconnect
Log("Trying to reconnect...")
connected = False
timer1.Enabled = True
End Sub
Private Sub Timer1_Tick
timer1.Enabled = False
Connect
End Sub
Private Sub astream_NewData (Buffer() As Byte)
If Buffer.Length >=6 Then
Log("status=" & Buffer(1))
Else
Log("Invalid response")
End If
End Sub
Private Sub astream_Error
Log("error: " & LastException)
Reconnect
End Sub
Private Sub astream_Terminated
Log("terminated")
Reconnect
End Sub
Public Sub SendMessageTo(Devices As List, msg As Message)
Dim out As OutputStream
out.InitializeToBytesArray(0)
For Each device As String In Devices
Dim dm As IOS_DeviceAndMessage
dm.Initialize
dm.Device = device
dm.Msg = msg
queue.Add(dm)
Next
queueTimer.Enabled = True
End Sub
Private Sub QueueTimer_Tick
Log($"QueueTimer_Tick, queue size=${queue.Size}."$)
If Not(connected) Then Return
If queue.Size = 0 Then
queueTimer.Enabled = False
Return
End If
Dim out As OutputStream
out.InitializeToBytesArray(0)
Dim numberOfTokens As Int = 1
Do While queue.Size > 0 And numberOfTokens <= NUMBER_OF_TOKENS_PER_REQUEST
numberOfTokens = numberOfTokens + 1
Dim dm As IOS_DeviceAndMessage = queue.Get(0)
queue.RemoveAt(0)
Log(dm.Device)
Dim FrameData As OutputStream
FrameData.InitializeToBytesArray(0)
WriteItem(FrameData, 1, bc.HexToBytes(dm.device))
Dim jg As JSONGenerator
Dim m As Map = CreateMap("alert": CreateMap("title": dm.Msg.Title, "body": dm.msg.Text), "badge": dm.msg.Badge)
If dm.msg.Sound Then m.Put("sound", "default")
jg.Initialize(CreateMap("aps":m))
'jg.Initialize(CreateMap("aps":CreateMap("content-available": 1), "Key1": "Value1"))
WriteItem(FrameData,2, jg.ToString.GetBytes("UTF8"))
WriteItem(FrameData,3, bc.IntsToBytes(Array As Int(Rnd(0, 9999999))))
WriteItem(FrameData,4, bc.IntsToBytes(Array As Int(dm.msg.ExpirationDate / 1000)))
Dim p As Byte
If dm.msg.HighPriority Then p = 10 Else p = 5
WriteItem(FrameData,5, Array As Byte(p))
Dim payload() As Byte = FrameData.ToBytesArray
out.WriteBytes(Array As Byte(2), 0, 1)
out.WriteBytes(bc.IntsToBytes(Array As Int(payload.Length)), 0, 4)
out.WriteBytes(payload, 0, payload.Length)
Loop
astream.Write(out.ToBytesArray)
End Sub
Private Sub WriteItem(out As OutputStream, id As Byte, data() As Byte)
out.WriteBytes(Array As Byte(id), 0, 1)
out.WriteBytes(bc.ShortsToBytes(Array As Short(data.Length)), 0, 2)
out.WriteBytes(data, 0, data.Length)
End Sub