我一整天都被困在这里.我有一个非常简单的ActionCable示例应用程序(聊天应用程序)由David Heinemeier Hansson正常工作(
https://www.youtube.com/watch?v=n0WUjGkDFS0).
@H_404_2@我试图用iPhone应用程序打到websocket连接.当我连接到ws:// localhost:3000 / cable时,我可以收到ping,但是我不太确定如何从JavaScript上下文中订阅频道.
解决方法
哦,我看完这个问题后也经历了这个问题.
@H_404_2@过了一会儿,我终于发现了这个神奇的Github问题页面:
@H_404_2@https://github.com/rails/rails/issues/22675
>使用PocketSocket框架进行Web套接字连接
> Rails 5 RC1
> Ruby 2.2.4p230 @H_404_2@我假设你知道如何使用Cocoapods来安装PocketSocket. @H_404_2@相关规范如下: @H_404_2@ViewController.h
>编辑您的Rail的配置>环境> development.rb文件放在以下行之前的某个地方,如end关键字之前: @H_404_2@Rails.application.config.action_cable.allowed_request_origins = [‘http://10.1.1.10:3000’]
>使用以下命令启动Rails服务器: @H_404_2@rails server -b 0.0.0.0
>构建并运行您的iPhone应用程序到iPhone设备上.您现在应该可以连接和发送消息:D @H_404_2@我从以下链接中获得了这些解决方案: @H_404_2@Request origin not allowed: http://localhost:3001 when using Rails5 and ActionCable @H_404_2@Rails 4.2 server; private and public ip not working @H_404_2@希望能在未来帮助别人.
@H_404_2@I do understand that this patch would break some tests. That is not@H_404_2@我终于得到了iOS应用程序订阅房间频道,按照Github用户对Rails问题的建议. @H_404_2@我的设置如下: @H_404_2@目标C
surprising to me. But the original issue I believe is still relevant
and shouldn’t be closed. @H_404_2@The following JSON sent to the server should succeed: @H_404_2@{“command”: “subscribe”,”identifier”:{“channel”:”ChangesChannel”}} @H_404_2@It does not! Instead you must send this: @H_404_2@{“command”:
“subscribe”,”identifier”:”{\”channel\”:\”ChangesChannel\”}”}
>使用PocketSocket框架进行Web套接字连接
> Rails 5 RC1
> Ruby 2.2.4p230 @H_404_2@我假设你知道如何使用Cocoapods来安装PocketSocket. @H_404_2@相关规范如下: @H_404_2@ViewController.h
#import <PocketSocket/PSWebSocket.h> @interface ViewController : UIViewController <PSWebSocketDelegate,UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate> @property (nonatomic,strong) PSWebSocket *socket;@H_404_2@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"); }@H_404_2@重要的提示: @H_404_2@我还挖了一下订阅类源代码:
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@H_404_2@注意行:
connection.server.channel_classes[id_options[:channel]]@H_404_2@我们需要使用该通道的类名. @H_404_2@DHH YouTube视频使用“room_channel”作为房间名称,但该频道的类文件名为“RoomChannel”. @H_404_2@我们需要使用类名称而不是通道的实例名称. @H_404_2@发送消息 @H_404_2@为了防止别人想知道如何发送消息,这里是我的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]; }@H_404_2@这假定您已经连接了您的UITextField来处理按住返回键或某些“发送”按钮的UI. @H_404_2@这个整个演示应用程序是一个快速的黑客,显然,如果我要在一个真正的应用程序中,我会使我的代码更干净,更可重用,并将其抽象为一个类. @H_404_2@从真正的iPhone设备连接到Rails服务器: @H_404_2@为了iPhone应用程序可以在实际的设备上与Rails服务器通话,而不是iPhone模拟器. @H_404_2@执行以下操作: @H_404_2@检查您的计算机的TCP / IP地址.例如,在我的iMac上,有些日子可能是10.1.1.10(如果使用DHCP,将来可能会自动更改).
>编辑您的Rail的配置>环境> development.rb文件放在以下行之前的某个地方,如end关键字之前: @H_404_2@Rails.application.config.action_cable.allowed_request_origins = [‘http://10.1.1.10:3000’]
>使用以下命令启动Rails服务器: @H_404_2@rails server -b 0.0.0.0
>构建并运行您的iPhone应用程序到iPhone设备上.您现在应该可以连接和发送消息:D @H_404_2@我从以下链接中获得了这些解决方案: @H_404_2@Request origin not allowed: http://localhost:3001 when using Rails5 and ActionCable @H_404_2@Rails 4.2 server; private and public ip not working @H_404_2@希望能在未来帮助别人.