Ind.ie is now Small Technology Foundation.
Commit 775f6401 authored by Dapperstout's avatar Dapperstout

Refactor: move LocalDevice and RemoteDevice into their own files.

parent 44d4cb3b
This diff is collapsed.
import Foundation
import SwiftBytes
import CocoaAsyncSocket
public class RemoteDevice {
public let host: NSString
public let port: UInt16
public let id: DeviceId
public init(host: NSString, port: UInt16 = 22000, id: DeviceId) {
self.host = host
self.port = port
self.id = id
}
}
public class LocalDevice: NSObject {
public typealias ConnectionHandler = (Connection?) -> ()
public typealias MessageHandler = (Message) -> ()
public typealias ErrorHandler = (NSError) -> ()
let localIdentity: SecIdentity
public init(localIdentity: SecIdentity) {
self.localIdentity = localIdentity
}
public func connect(remoteDevice: RemoteDevice,
onConnection: ConnectionHandler = { _ in },
onMessage: MessageHandler = { _ in },
onError: ErrorHandler = { _ in }
) {
socket.synchronouslySetDelegateQueue(queue)
socket.synchronouslySetDelegate(self) // don't actually need delegate here, but without it, connectToHost doesn't work...
do {
try socket.connectToHost(remoteDevice.host as String, onPort: remoteDevice.port)
secure(socket, remoteDeviceId: remoteDevice.id, onConnection: onConnection, onMessage: onMessage, onError: onError)
}
catch _ {
onConnection(nil)
}
}
func secure(socket: GCDAsyncSocket, remoteDeviceId: DeviceId,
onConnection: ConnectionHandler,
onMessage: MessageHandler,
onError: ErrorHandler) {
tls.secureSocket(socket, remoteDeviceId: remoteDeviceId, localIdentity: localIdentity) { (Bool success) in
if success {
onConnection(SocketConnection(socket: self.socket, onMessage: onMessage, onError: onError))
} else {
onConnection(nil)
}
}
}
var socket: GCDAsyncSocket = GCDAsyncSocket()
var tls: TLS = TLS()
var queue = dispatch_get_main_queue()
}
public protocol Connection {
func send(message: Message)
func disconnect()
}
class SocketConnection: NSObject, GCDAsyncSocketDelegate, Connection {
let socket: GCDAsyncSocket
var incomingMessageBytes: [UInt8] = []
var onMessage: (Message) -> ()
var onError: (NSError) -> ()
init(socket: GCDAsyncSocket, onMessage: (Message) -> (), onError: (NSError) -> ()) {
self.socket = socket
self.onMessage = onMessage
self.onError = onError
super.init()
self.socket.synchronouslySetDelegate(self)
readHeader()
}
func send(message: Message) {
let data = NSData(bytes: message.encode().serialize())
self.socket.writeData(data, withTimeout:-1, tag: 0)
}
func disconnect() {
self.socket.disconnect()
}
func socket(socket: GCDAsyncSocket!, didReadData data: NSData!, withTag tag: Int) {
incomingMessageBytes += data.bytes
if tag == readingHeaderTag {
onHeaderRead(incomingMessageBytes)
}
if tag == readingContentsTag {
onContentsRead(incomingMessageBytes)
}
}
private func readHeader() {
socket.readDataToLength(8, withTimeout: timeout, tag: readingHeaderTag)
}
private func readContents(length length: UInt32) {
socket.readDataToLength(UInt(length), withTimeout: timeout, tag: readingContentsTag)
}
private func onHeaderRead(headerBytes: [UInt8]) {
let length = concatenateBytes(headerBytes[4], headerBytes[5], headerBytes[6], headerBytes[7])
if length > 0 {
readContents(length: length)
} else {
onContentsRead(headerBytes)
}
}
private func onContentsRead(messageBytes: [UInt8]) {
incomingMessageBytes = []
if let encodedMessage = EncodedMessage.deserialize(messageBytes) {
let message = Message.decode(encodedMessage)!
onMessage(message)
readHeader()
}
else {
disconnect()
onError(NSError(domain:PulseNSError.domain, code:PulseNSError.protocolError, userInfo:nil))
}
}
let readingHeaderTag = 0;
let readingContentsTag = 1;
let timeout: NSTimeInterval = 30;
}
\ No newline at end of file
import Foundation
import SwiftBytes
import CocoaAsyncSocket
public class LocalDevice: NSObject {
public typealias ConnectionHandler = (Connection?) -> ()
public typealias MessageHandler = (Message) -> ()
public typealias ErrorHandler = (NSError) -> ()
let localIdentity: SecIdentity
public init(localIdentity: SecIdentity) {
self.localIdentity = localIdentity
}
public func connect(remoteDevice: RemoteDevice,
onConnection: ConnectionHandler = { _ in },
onMessage: MessageHandler = { _ in },
onError: ErrorHandler = { _ in }
) {
socket.synchronouslySetDelegateQueue(queue)
socket.synchronouslySetDelegate(self) // don't actually need delegate here, but without it, connectToHost doesn't work...
do {
try socket.connectToHost(remoteDevice.host as String, onPort: remoteDevice.port)
secure(socket, remoteDeviceId: remoteDevice.id, onConnection: onConnection, onMessage: onMessage, onError: onError)
}
catch _ {
onConnection(nil)
}
}
func secure(socket: GCDAsyncSocket, remoteDeviceId: DeviceId,
onConnection: ConnectionHandler,
onMessage: MessageHandler,
onError: ErrorHandler) {
tls.secureSocket(socket, remoteDeviceId: remoteDeviceId, localIdentity: localIdentity) { (Bool success) in
if success {
onConnection(SocketConnection(socket: self.socket, onMessage: onMessage, onError: onError))
} else {
onConnection(nil)
}
}
}
var socket: GCDAsyncSocket = GCDAsyncSocket()
var tls: TLS = TLS()
var queue = dispatch_get_main_queue()
}
class SocketConnection: NSObject, GCDAsyncSocketDelegate, Connection {
let socket: GCDAsyncSocket
var incomingMessageBytes: [UInt8] = []
var onMessage: (Message) -> ()
var onError: (NSError) -> ()
init(socket: GCDAsyncSocket, onMessage: (Message) -> (), onError: (NSError) -> ()) {
self.socket = socket
self.onMessage = onMessage
self.onError = onError
super.init()
self.socket.synchronouslySetDelegate(self)
readHeader()
}
func send(message: Message) {
let data = NSData(bytes: message.encode().serialize())
self.socket.writeData(data, withTimeout:-1, tag: 0)
}
func disconnect() {
self.socket.disconnect()
}
func socket(socket: GCDAsyncSocket!, didReadData data: NSData!, withTag tag: Int) {
incomingMessageBytes += data.bytes
if tag == readingHeaderTag {
onHeaderRead(incomingMessageBytes)
}
if tag == readingContentsTag {
onContentsRead(incomingMessageBytes)
}
}
private func readHeader() {
socket.readDataToLength(8, withTimeout: timeout, tag: readingHeaderTag)
}
private func readContents(length length: UInt32) {
socket.readDataToLength(UInt(length), withTimeout: timeout, tag: readingContentsTag)
}
private func onHeaderRead(headerBytes: [UInt8]) {
let length = concatenateBytes(headerBytes[4], headerBytes[5], headerBytes[6], headerBytes[7])
if length > 0 {
readContents(length: length)
} else {
onContentsRead(headerBytes)
}
}
private func onContentsRead(messageBytes: [UInt8]) {
incomingMessageBytes = []
if let encodedMessage = EncodedMessage.deserialize(messageBytes) {
let message = Message.decode(encodedMessage)!
onMessage(message)
readHeader()
}
else {
disconnect()
onError(NSError(domain:PulseNSError.domain, code:PulseNSError.protocolError, userInfo:nil))
}
}
let readingHeaderTag = 0;
let readingContentsTag = 1;
let timeout: NSTimeInterval = 30;
}
\ No newline at end of file
public class RemoteDevice {
public let host: NSString
public let port: UInt16
public let id: DeviceId
public init(host: NSString, port: UInt16 = 22000, id: DeviceId) {
self.host = host
self.port = port
self.id = id
}
}
\ No newline at end of file
......@@ -4,7 +4,7 @@ import SwiftBytes
import CocoaAsyncSocket
@testable import Pulse
class ConnectionTests: QuickSpec {
class LocalDeviceTests: QuickSpec {
override func spec() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment