ruby-on-rails – 从iOS应用程序连接到ActionCable
我一整天都被困在这里.我有一个非常简单的ActionCable示例应用程序(聊天应用程序)由David Heinemeier Hansson正常工作(
https://www.youtube.com/watch?v=n0WUjGkDFS0).
我试图用iPhone应用程序打到websocket连接.当我连接到ws:// localhost:3000 / cable时,我可以收到ping,但是我不太确定如何从JavaScript上下文中订阅频道. 解决方法
哦,我看完这个问题后也经历了这个问题.
过了一会儿,我终于发现了这个神奇的Github问题页面: https://github.com/rails/rails/issues/22675
我终于得到了iOS应用程序订阅房间频道,按照Github用户对Rails问题的建议. 我的设置如下: 目标C 我假设你知道如何使用Cocoapods来安装PocketSocket. 相关规范如下: ViewController.h #import <PocketSocket/PSWebSocket.h> @interface ViewController : UIViewController <PSWebSocketDelegate,UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate> @property (nonatomic,strong) PSWebSocket *socket; ViewController.m - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view,typically from a nib. [self initViews]; [self initConstraints]; [self initSocket]; } -(void)initSocket { NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"ws://localhost:3000/cable"]]; self.socket = [PSWebSocket clientSocketWithRequest:request]; self.socket.delegate = self; [self.socket open]; } -(void)joinChannel:(NSString *)channelName { NSString *strChannel = @"{ "channel": "RoomChannel" }"; id data = @{ @"command": @"subscribe",@"identifier": strChannel }; NSData * jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:nil]; NSString * myString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSLog(@"myString= %@",myString); [self.socket send:myString]; } #pragma mark - PSWebSocketDelegate Methods - -(void)webSocketDidOpen:(PSWebSocket *)webSocket { NSLog(@"The websocket handshake completed and is now open!"); [self joinChannel:@"RoomChannel"]; } -(void)webSocket:(PSWebSocket *)webSocket didReceiveMessage:(id)message { NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding]; id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSString *messageType = json[@"type"]; if(![messageType isEqualToString:@"ping"] && ![messageType isEqualToString:@"welcome"]) { NSLog(@"The websocket received a message: %@",json[@"message"]); [self.messages addObject:json[@"message"]]; [self.tableView reloadData]; } } -(void)webSocket:(PSWebSocket *)webSocket didFailWithError:(NSError *)error { NSLog(@"The websocket handshake/connection failed with an error: %@",error); } -(void)webSocket:(PSWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean { NSLog(@"The websocket closed with code: %@,reason: %@,wasClean: %@",@(code),reason,(wasClean) ? @"YES": @"NO"); } 重要的提示: 我还挖了一下订阅类源代码: def add(data) id_key = data['identifier'] id_options = ActiveSupport::JSON.decode(id_key).with_indifferent_access subscription_klass = connection.server.channel_classes[id_options[:channel]] if subscription_klass subscriptions[id_key] ||= subscription_klass.new(connection,id_key,id_options) else logger.error "Subscription class not found (#{data.inspect})" end end 注意行: connection.server.channel_classes[id_options[:channel]] 我们需要使用该通道的类名. DHH YouTube视频使用“room_channel”作为房间名称,但该频道的类文件名为“RoomChannel”. 我们需要使用类名称而不是通道的实例名称. 发送消息 为了防止别人想知道如何发送消息,这里是我的iOS代码向服务器发送消息: -(void)sendMessage:(NSString *)message { NSString *strMessage = [[NSString alloc] initWithFormat:@"{ "action": "speak","message": "%@" }",message]; NSString *strChannel = @"{ "channel": "RoomChannel" }"; id data = @{ @"command": @"message",@"identifier": strChannel,@"data": strMessage }; NSData * jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:nil]; NSString * myString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSLog(@"myString= %@",myString); [self.socket send:myString]; } 这假定您已经连接了您的UITextField来处理按住返回键或某些“发送”按钮的UI. 这个整个演示应用程序是一个快速的黑客,显然,如果我要在一个真正的应用程序中,我会使我的代码更干净,更可重用,并将其抽象为一个类. 从真正的iPhone设备连接到Rails服务器: 为了iPhone应用程序可以在实际的设备上与Rails服务器通话,而不是iPhone模拟器. 执行以下操作: 检查您的计算机的TCP / IP地址.例如,在我的iMac上,有些日子可能是10.1.1.10(如果使用DHCP,将来可能会自动更改). Rails.application.config.action_cable.allowed_request_origins = [‘http://10.1.1.10:3000’] rails server -b 0.0.0.0 我从以下链接中获得了这些解决方案: Request origin not allowed: http://localhost:3001 when using Rails5 and ActionCable Rails 4.2 server; private and public ip not working 希望能在未来帮助别人. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |