Skip to content

Commit 1e1bf5c

Browse files
committed
save changes
1 parent 7ff5d79 commit 1e1bf5c

13 files changed

+340
-38
lines changed

Package.swift

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import PackageDescription
55

66
let package = Package(
77
name: "StompClientKit",
8+
9+
platforms: [
10+
.iOS(.v13),
11+
],
12+
813
products: [
914
// Products define the executables and libraries produced by a package, and make them visible to other packages.
1015
.library(

Sources/StompClientKit/Command.swift

-15
This file was deleted.

Sources/StompClientKit/CommandID.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
import Foundation
99

10-
public enum CommandID {
10+
public enum CommandID: String {
11+
case NONE
1112
case STOMP
1213
case CONNECT
1314
case DISCONNECT
@@ -23,5 +24,4 @@ public enum CommandID {
2324
case MESSAGE
2425
case RECEIPT
2526
case ERROR
26-
2727
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by gridscale on 2020/05/01.
6+
//
7+
8+
import Foundation
9+
10+
public enum ControlChars : String {
11+
case NULL = "¥0"
12+
case LF = "¥n"
13+
case CR = "¥r"
14+
case COLON = ":"
15+
}

Sources/StompClientKit/Frame.swift

+120
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,123 @@
66
//
77

88
import Foundation
9+
10+
public struct Frame {
11+
12+
private var cid : CommandID = .CONNECT
13+
private var headers: [FrameHeader] = []
14+
private var body: FrameBody = FrameBody()
15+
16+
//
17+
public init(command id: CommandID ) {
18+
cid = id
19+
}
20+
21+
//
22+
public mutating func addHeader(_ header: FrameHeader) {
23+
self.headers.append(header)
24+
}
25+
26+
//
27+
public func toData(using encoding: String.Encoding = .utf8) -> Data? {
28+
var s = ""
29+
s += cid.rawValue
30+
s += ControlChars.LF.rawValue
31+
32+
for h in headers {
33+
s += h.text() + ControlChars.LF.rawValue
34+
}
35+
36+
s += ControlChars.LF.rawValue
37+
s += body.text
38+
s += ControlChars.NULL.rawValue
39+
40+
return s.data(using: encoding)
41+
42+
}
43+
44+
var isConnected : Bool {
45+
return (cid == CommandID.CONNECTED)
46+
}
47+
48+
var isReceipt : Bool {
49+
return (cid == CommandID.RECEIPT)
50+
}
51+
52+
53+
var isMessage : Bool {
54+
return (cid == CommandID.MESSAGE)
55+
}
56+
57+
var isError : Bool {
58+
return (cid == CommandID.ERROR)
59+
}
60+
61+
//
62+
static public func connectFrame(versions: String = "1.2,1.1") -> Frame {
63+
var f = Frame(command: .CONNECT)
64+
f.headers.append(FrameHeader(k: Headers.ACCEPT_VERSION.rawValue, v: versions))
65+
return f;
66+
}
67+
}
68+
69+
public struct FrameHeader {
70+
var key: String
71+
var value: String
72+
73+
//
74+
//
75+
public init(k: String, v:String) {
76+
self.key = k
77+
self.value = v
78+
}
79+
80+
//
81+
public func text() -> String {
82+
return key + ControlChars.COLON.rawValue + value
83+
}
84+
}
85+
86+
//
87+
public enum Headers: String {
88+
case ACCEPT_VERSION = "accept-version"
89+
case HEART_BEATE = "heart-beat"
90+
case VERSION = "version"
91+
case HOST = "host"
92+
case CONTENT_TYPE = "content-type"
93+
case CONTENT_LENGTH = "content-length"
94+
95+
}
96+
97+
98+
public struct FrameBody {
99+
private var data : Data = Data()
100+
private var encoding = String.Encoding.utf8
101+
102+
//
103+
public var text : String {
104+
let t = String(data: data, encoding: encoding)
105+
if (t == nil) {
106+
return ""
107+
} else {
108+
return t!
109+
}
110+
}
111+
}
112+
113+
//
114+
public class FrameParser {
115+
private var stompVersion : StompVersions = .UNKNOWN
116+
117+
public var resultFrame : Frame?
118+
119+
//
120+
public init(as version: StompVersions) {
121+
self.stompVersion = version
122+
}
123+
124+
//
125+
public func parse(text: String) {
126+
127+
}
128+
}

Sources/StompClientKit/StompClient.swift

+148-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,156 @@
66
//
77

88
import Foundation
9+
import Starscream
910

10-
public class StompClient {
11+
//
12+
public typealias MessageHandler = (_ frame : Frame) -> Any
13+
14+
public class StompClient : WebSocketDelegate {
15+
16+
private var endpoint: URL
17+
private var handler : MessageHandler = {_ in }
18+
private var underlyWebsocket : WebSocket
19+
20+
public var wsConnected = false
21+
22+
// status of stomp client
23+
// CONNECTING -> CONNECTED -> DISCONNECTED
24+
public var status = StompStatus.STARTING
25+
26+
// STOMP Protocol version
27+
// initially UNKNOWN was set, after handshake, the really version will be set.
28+
private var version = StompVersions.UNKNOWN
29+
30+
// STOMP Heart beat value. 0 means not send.
31+
private var heartbeat = 0
32+
33+
// On Connected Handling callback hook.
34+
private var onConnected : (_ client: StompClient) -> Any = {_ in }
35+
36+
// intilize the underlying websocket object.
37+
// at this point, the websocket had not connected to server yet.
38+
public init(endpoint url : String) {
39+
self.endpoint = URL(string: url)!
40+
var request = URLRequest(url: endpoint)
41+
42+
request.timeoutInterval = 5
43+
underlyWebsocket = WebSocket(request: request)
44+
underlyWebsocket.delegate = self
45+
}
46+
47+
//
48+
public func startConnect () {
49+
underlyWebsocket.connect()
50+
}
51+
52+
//
53+
public func subscribe(to topic : String, handleby handler: @escaping MessageHandler) -> StompClient {
54+
let data = ("SUBSCRIBE\nid:sub-0\n"
55+
+ "destination:" + topic + "\n"
56+
+ "ack:client\n\n\0"
57+
).data(using: .utf8)!
58+
59+
underlyWebsocket.write(data: data)
60+
61+
self.handler = handler
62+
return self
63+
}
64+
65+
//
66+
public func disconnect() {
67+
68+
}
69+
70+
//
71+
public func send(_ msg: String) {
72+
73+
}
74+
75+
//
76+
public func didReceive(event: WebSocketEvent, client: WebSocket) {
77+
switch event {
78+
case .connected(let headers):
79+
wsConnected = true
80+
print("websocket is connected: \(headers)")
81+
let command = Frame.connectFrame(versions: "1.2,1.1")
82+
83+
let data = command.toData()!
84+
85+
underlyWebsocket.write(data: data)
86+
87+
case .disconnected(let reason, let code):
88+
wsConnected = false
89+
print("websocket is disconnected: \(reason) with code: \(code)")
90+
91+
case .text(let string):
92+
print("Received text: \(string)")
93+
// handle stomp frame
94+
handleFrame(text: string)
95+
96+
case .binary(let data):
97+
// Exception: a stomp client expects no binary data
98+
print("Received data: \(data.count)")
99+
100+
case .ping(_):
101+
break
102+
103+
case .pong(_):
104+
break
105+
106+
case .viabilityChanged(_):
107+
break
108+
109+
case .reconnectSuggested(_):
110+
break
111+
112+
case .cancelled:
113+
wsConnected = false
114+
115+
case .error(let error):
116+
wsConnected = false
117+
handleError(error )
118+
}
119+
}
120+
121+
// Handle Frame text from server, update client status or call message handler
122+
// according to the content of the frame.
123+
func handleFrame(text: String) {
124+
// check
125+
126+
let parser = FrameParser(as: .VER1_2)
127+
parser.parse(text: text)
128+
129+
let frame = parser.resultFrame
130+
131+
if (frame == nil) {
132+
return
133+
}
134+
135+
// if CONNECTED
136+
if (frame!.isConnected) {
137+
status = .CONNECTED
138+
// retrieve heart beat
139+
// retrieve protocol version
140+
141+
// call back to onConnected function
142+
143+
} else if ( frame!.isMessage) {
144+
// if MESSAGE
145+
146+
} else if ( frame!.isReceipt) {
147+
// if RECEIPT
148+
149+
} else if ( frame!.isError) {
150+
// if ERROR
151+
152+
} else {
153+
// exception
154+
}
155+
}
11156

12-
public init() {
157+
//
158+
func handleError(_ error : Error?) {
13159

14160
}
15161
}
+10-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1-
struct StompClientKit {
2-
var text = "Hello stomp!"
1+
public struct StompClientKit {
2+
public let version = "1.0.0"
33
}
4+
5+
public enum StompVersions {
6+
case VER1_0
7+
case VER1_1
8+
case VER1_2
9+
case UNKNOWN
10+
}
11+
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by gridscale on 2020/04/30.
6+
//
7+
8+
import Foundation
9+
10+
public enum StompStatus {
11+
case STARTING
12+
case CONNECTING
13+
case DISCONNECTED
14+
case CONNECTED
15+
}

Sources/StompClientKit/Subscribe.swift

-8
This file was deleted.
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by gridscale on 2020/04/28.
6+
//
7+
8+
import Foundation
9+
10+
class TextDecoder {
11+
12+
}

0 commit comments

Comments
 (0)