iOS Socket.io -ios的使用

Socket.io -ios

socket.io-ios简介 
你可以使用socket.io通过swift编写在iOS和OS的客户端上. 同时保持简单表现良好的JavaScript客户端.

import Foundation
let socket = SocketIOClient(socketURL: "localhost:8880")
socket.on("important message") {data, ack in
    println("Message for you! \(data?[0])")
    ack?("I got your message, and I'll send my response")
    socket.emit("response", "Hello!")
}
socket.connect()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

xxoo -demo : 通过这个demo,展示如何使用它们在真实的项目中. 

概述

在本教程中,我们将创建一个小iOS程序,演示socket.io. 你可以通过观察这些代码学的更好;本教程重点不是解释iOS,所以你要有一定的XCode基础. 引入socket.io-client-swift.

若要在OC中使用

设置项目

从xcode中创建一个新项目, 取一个名字.我的命名可TicTacIOiOS

下一步是获取socket.o-client-swift代码,你可以使用git clone或者是下载一个发行版本. 之后将它添加到你的项目, 简单的拖动SocketRocket文件到新建组名’SwiftIO’中,确保选择的复制.

可以编译一下.

加入我们的代码

现在,假设你已经创建了你的UI界面, 是时候添加代码将于我们的socket.io接口服务器.

  • 1.在我们的demo中, 有一个UIViewControl子类,我们将所有代码添加到这里. 首先, 我们需要添加一个SocketIOClient类型的成员socket.
let socket = SocketIOClient(socketURL:"localhost:8900")
  • 1
  • 2.接着: 在viewDidLoad方法里面,我们需要做两件事: 一个处理socket的方法,一个连接socket的方法.
self.addHandlers()
self.socket.connect()
  • 1
  • 2
func addHandlers(){
    // our socket handlers go here
}
  • 1
  • 2
  • 3

因为我们要添加处理程序,我认为值得一提的是swift语法的闭包形式. 
我不会告你你们示例程序的所有细节, 只说明你需要知道的几个重要的事,当你使用socket.io-client-swift时. 

  • 3.第一个handler方法我们会添加一个任意呼叫的事件, 作为有用的调试API. 
// 使用闭包的速记参数.
self.socket.onAny {println("Got event: \($0.event), with items: \($0.items)")}
  • 1
  • 2
  • 4.我们添加的下一个handler 是一个告诉app游戏开始时
self.socket.on("startGame") {[weak self] data, ack in
    self?.handleStart()
    return
}
  • 1
  • 2
  • 3
  • 4

现在来解释一些事: [weak self]防循环引用.当socket对象超出范围时,保证回收.第一个参数: 回调可选的NSArray类型,它将包含所有接收到的数据和事件或是nil. 第二个参数 回调可选的AckEmitter类型, 这只是补充参数, 后面会用到.

  • 5.我们添加下一个handler(句柄) 是程序成功时.
self.socket.on("win") {[weak self] data, ack in
    if let name = data?[0] as? String, typeDict = data?[1] as? NSDictionary {
        self?.handleWin(name, type: typeDict)
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5

如上所述, 要注意的是,几乎所有的数据处理程序, 你会做一些可选的展开, 这是一个使用JavaScript的不幸产物.

  • 6.最后.一个handler,是处理玩家是否想玩了.
self.socket.on("gameReset") {data, ack in
    ack?(false)
}
  • 1
  • 2
  • 3

在这个简化的例子中, 我们只需要向服务器发送一个请求, 我们不再玩了,记住AckEmitter有一个可变的定义,所以你想要可以一次发送多个事件.

Emttting 事件

接下来你可能想知道是如何从客户端发送事件的, 其实和socket.io-client几乎一样.

在我们的ViewController中,我们有一个方法来处理 当用户想动的时候, 我们将展示如何向服务器发送数据,先不论逻辑.

@IBAction func btnClicked(btn:UIButton) {
    let coord:(x:Int, y:Int)
    //决定coord 
    self.socket.emit("playerMove", coord.x, coord.y)
}
  • 1
  • 2
  • 3
  • 4
  • 5

这是你所有要发送的数据. 一些其他的发送例子demo不演示.

发送JSON

如前所述,JSON在swift是最好的字典,值得庆幸的是,你不需要把它转换其他的格式为了通过socket.io .

let myJSON = [
    "name": "bob"
] 
socket.emit("jsonTest", myJSON)
  • 1
  • 2
  • 3
  • 4

发送二进制数据

二级制数据也可,你也无需担心.

let data = "Hello, ".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let data2 = "World".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!

socket.emit("dataTest", data, ["world": data2])
  • 1
  • 2
  • 3
  • 4

Acks请求(接收方表示确认发来的数据已经接收无误)

客户端还可以请求发送事件的ACK, 这是通过使用emitWithAck方法返回的对象. 你可以添加一个这个handler.

socket.emitWithAck("needsAck", "test").onAck {data in
    println("got ack with data: (data)")
}
  • 1
  • 2
  • 3

iOS的会话

iOS非常限制后台, 因此,不要指望你的socket连接在后台不会断开. 所以最好创建一个任务.进入后台时主动关闭连接. 需要时再重新连接.

Socket.io-Client-Swift框架的使用

github.

示例

let socket = SocketIOClient(socketURL: NSURL(string: "http://localhost:8080")!, options: [.Log(true), .ForcePolling(true)])

socket.on("connect") {data, ack in
    print("socket connected")
}
//开始
socket.on("currentAmount") {data, ack in
    if let cur = data[0] as? Double {
        socket.emitWithAck("canUpdate", cur)(timeoutAfter: 0) {data in
            socket.emit("update", ["amount": cur + 2.50])
        }
        ack.with("Got your currentAmount", "dude")
    }
}

socket.connect()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

ObjC中示例

NSURL* url = [[NSURL alloc] initWithString:@"http://localhost:8080"];
SocketIOClient* socket = [[SocketIOClient alloc] initWithSocketURL:url options:@{@"log": @YES, @"forcePolling": @YES}];

[socket on:@"connect" callback:^(NSArray* data, SocketAckEmitter* ack) {
    NSLog(@"socket connected");
}];

[socket on:@"currentAmount" callback:^(NSArray* data, SocketAckEmitter* ack) {
    double cur = [[data objectAtIndex:0] floatValue];

    [socket emitWithAck:@"canUpdate" withItems:@[@(cur)]](0, ^(NSArray* data) {
        [socket emit:@"update" withItems:@[@{@"amount": @(cur + 2.50)}]];
    });

    [ack with:@[@"Got your currentAmount, ", @"dude"]];
}];

[socket connect];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

1.手动添加 .

直接拖入项目即可,确保是复制选项.

2.作为Swift 包管理工具添加

import PackageDescription

let package = Package(
    name: "YourSocketIOProject",
    dependencies: [
        .Package(url: "https://github.com/socketio/socket.io-client-swift", majorVersion: 5)
    ]
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这时import SocketIOClientSwift

3. 使用Carthage添加

添加这行命令到Cartfile

github "socketio/socket.io-client-swift" ~> 6.0.0 # Or latest version
  • 1
  • 2

运行 carthage update --platform iOS,machos

4. 使用 CocoaPods添加

Pod file文件中添加 pod 'Socket.IO-Client-Swift'

API

构造函数

init(var socketURL: NSURL, options: Set = [])
  • 1

创建一个新的SocketIOClient. 参数option是 SocketIOClientOption的设置.如果你的socket.io服务器是要安全的,你需要指定https在你的socketURL参数中.

convenience init(socketURL: NSURL, options: NSDictionary?)
  • 1

同上, 但是为了ObjC准备,使用字典.

Options

所有关于SocketIOClientOption的设置.如果是ObjC,转换名字lowerCamelCase.

case ConnectParams([String: AnyObject]) // 通过字典内容连接
case Cookies([NSHTTPCookie]) // An array of NSHTTPCookies. Passed during the handshake. Default is nil.
case DoubleEncodeUTF8(Bool) // Whether or not to double encode utf8. If using the node based server this should be true. Default is true.
case ExtraHeaders([String: String]) // 添加自定义请求头初始化来请求, 默认为nil
case ForcePolling(Bool) // 是否使用 xhr-polling. Default is `false`
case ForceNew(Bool) // 将为每个连接创建一个新的connect, 如果你在重新连接时有bug时使用.
case ForceWebsockets(Bool) // 是否使用 WebSockets. Default is `false`
case HandleQueue(dispatch_queue_t) // 调度handle的运行队列. Default is the main queue.
case Log(Bool) // 是否打印调试信息. Default is false.
case Logger(SocketLogger) // 可自定义SocketLogger调试日志.默认是系统的.
case Nsp(String) // 如果使用命名空间连接. Must begin with /. Default is `/`
case Path(String) // 如果服务器使用一个自定义路径. 例如: `"/swift/"`. Default is `""`
case Reconnects(Bool) // 是否重新连接服务器失败. Default is `true`
case ReconnectAttempts(Int) // 重新连接多少次. Default is `-1` (无限次)
case ReconnectWait(Int) // 等待重连时间. Default is `10`
case SessionDelegate(NSURLSessionDelegate) // NSURLSessionDelegate 底层引擎设置. 如果你需要处理自签名证书. Default is nil.
case Secure(Bool) // 如果连接要使用TLS. Default is false.
case SelfSigned(Bool) //  WebSocket.selfSignedSSL设置 (Don't do this, iOS will yell at you)
case VoipEnabled(Bool) // 如果你的客户端使用VoIP服务,只有用这个选项,Default is false
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

方法

on(event: String, callback: NormalCallback) -> NSUUID // 给一个事件添加一个句柄. Items are passed by an array. 可以发送ack请求. 例如,返回一个唯一ID.
once(event: String, callback: NormalCallback) -> NSUUID // 同上,但只执行一次.
onAny(callback:((event: String, items: AnyObject?)) -> Void) //可以给所有事件添加一个句柄. event可以接收任何事件.
emit(event: String, _ items: AnyObject...) // 发送一个或多条消息.
emit(event: String, withItems items: [AnyObject]) // emit for Objective-C
emitWithAck(event: String, _ items: AnyObject...) -> (timeoutAfter: UInt64, callback: (NSArray?) -> Void) -> Void // 给服务器发送一个ack确认请求. 返回一个函数,你可以用它添加一个句柄. 注意: 直到你调用这个返回函数,才会发送消息
emitWithAck(event: String, withItems items: [AnyObject]) -> (UInt64, (NSArray?) -> Void) -> Void // 同上,为Objective-C准备的 
connect() // 建立一个连接到服务器. 连接成功会触发 "connect"事件
connect(timeoutAfter timeoutAfter: Int, withTimeoutHandler handler: (() -> Void)?) // 连接到服务器. 如果连接超时,会调用handle
disconnect() // Closes the socket. 重开一个断开连接的socket还没完全测试.
reconnect() // Causes the client to reconnect to the server.
joinNamespace(namespace: String) - Causes the client to join namespace. 不应该被调用,除非你手动改变命名空间.
leaveNamespace() // Causes the client to leave the nsp and go back to '/'
off(event: String) - Removes all event handlers for event.
off(id id: NSUUID) - Removes the event that corresponds to id.
removeAllHandlers() - Removes all handlers.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

客户端的事件

  1. connect – 当成功连接时Emitted
  2. disconnect – 当连接断开Emitted
  3. error – 发送错误时Emitted
  4. reconnect – 当开始重连时Emitted
  5. reconnectAttempt – 当尝试重连时Emitted

你可能感兴趣的:(iOS Socket.io -ios的使用)