将 iOS 应用程序连接到 Amazon 上托管的 Ejabberd 服务器

Posted

技术标签:

【中文标题】将 iOS 应用程序连接到 Amazon 上托管的 Ejabberd 服务器【英文标题】:Connecting iOS app to Ejabberd Server hosted on Amazon 【发布时间】:2017-06-04 05:53:51 【问题描述】:

我在亚马逊上托管Ejabberd聊天服务器并在那里添加了两个用户,当我尝试通过Adium连接Ejabberd服务器时,它要求证书然后才连接,现在我正在@987654323开发聊天应用程序@ 使用 Ejabberd 服务器和 XMPP,我配置了所有代码,传递了主机名和端口号:5222,但它没有连接到服务器。 我是否需要编写程序来获取服务器证书并将我的计算机证书 (.p12) 文件传递​​给服务器?

注意:我在 localhost 中并通过 ios Swift 代码配置了 Ejabberd 服务器,当我从 iOS 应用程序发送消息然后它显示在 Adium 中并且当 Adium 用户发送消息然后我转到 Ejabberd 时,它运行良好Web 管理面板,可以查看离线消息。

这是连接亚马逊托管的 Ejabberd 的 Swift 代码:

//
//  AppDelegate.swift
//  Thanks to Process One for this.

import UIKit
import XMPPFramework

protocol ChatDelegate 
    func buddyWentOnline(_ name: String)
    func buddyWentOffline(_ name: String)
    func didDisconnect()


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, XMPPRosterDelegate, XMPPStreamDelegate 

    var window: UIWindow?
    var delegate:ChatDelegate! = nil
    let xmppStream = XMPPStream()
    let xmppRosterStorage = XMPPRosterCoreDataStorage()
    var xmppRoster: XMPPRoster

    override init() 
        xmppRoster = XMPPRoster(rosterStorage: xmppRosterStorage)
    

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
        // Override point for customization after application launch.

        DDLog.add(DDTTYLogger.sharedInstance())

        setupStream()

        return true
    

    func applicationWillResignActive(_ application: UIApplication) 
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
        disconnect()
    

    func applicationDidEnterBackground(_ application: UIApplication) 
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    

    func applicationWillEnterForeground(_ application: UIApplication) 
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    

    func applicationDidBecomeActive(_ application: UIApplication) 
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
        connect()
    

    func applicationWillTerminate(_ application: UIApplication) 
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    

    //MARK: Private Methods
     func setupStream() //fileprivate
        //xmppRoster = XMPPRoster(rosterStorage: xmppRosterStorage)
        xmppRoster.activate(xmppStream)
        xmppStream?.addDelegate(self, delegateQueue: DispatchQueue.main)
        xmppRoster.addDelegate(self, delegateQueue: DispatchQueue.main)
    

     func goOnline()  //fileprivate
        let presence = XMPPPresence()
        let domain = xmppStream?.myJID.domain

        if domain == "gmail.com" || domain == "gtalk.com" || domain == "talk.google.com" 
            let priority = DDXMLElement.element(withName: "priority", stringValue: "24") as! DDXMLElement
            presence?.addChild(priority)
        

        xmppStream?.send(presence)
    

     func goOffline()  //fileprivate
        let presence = XMPPPresence(type: "unavailable")
        xmppStream?.send(presence)
    

    func connect() -> Bool 
        xmppStream.hostName = "amazon hosted ejabber ip address"
        xmppStream.hostPort=5222
        if !(xmppStream?.isConnected())! 
            let jabberID = UserDefaults.standard.string(forKey: "userID")
            let myPassword = UserDefaults.standard.string(forKey: "userPassword")

            if !(xmppStream?.isDisconnected())! 
                return true
            
            if jabberID == nil && myPassword == nil 
                return false
            


            xmppStream?.myJID = XMPPJID.init(string: jabberID)

            do 
                try xmppStream?.connect(withTimeout: XMPPStreamTimeoutNone)
                print("Connection success")
                return true
             catch 
                print("Something went wrong!")
                return false
            
         else 
            return true
        
    

    func disconnect() 
        goOffline()
        xmppStream?.disconnect()
    

    //MARK: XMPP Delegates
    func xmppStreamDidConnect(_ sender: XMPPStream!) 
        do 
            try xmppStream?.authenticate(withPassword: UserDefaults.standard.string(forKey: "userPassword"))
         catch 
            print("Could not authenticate")
        
    

    func xmppStreamDidAuthenticate(_ sender: XMPPStream!) 
        goOnline()
    

    func xmppStream(_ sender: XMPPStream!, didReceive iq: XMPPIQ!) -> Bool 
        print("Did receive IQ")
        return false
    

    func xmppStream(_ sender: XMPPStream!, didReceive message: XMPPMessage!) 
        print("Did receive message \(message)")
    

    func xmppStream(_ sender: XMPPStream!, didSend message: XMPPMessage!) 
        print("Did send message \(message)")
    

    func xmppStream(_ sender: XMPPStream!, didReceive presence: XMPPPresence!) 
        let presenceType = presence.type()
        let myUsername = sender.myJID.user
        let presenceFromUser = presence.from().user

        if presenceFromUser != myUsername 
            print("Did receive presence from \(presenceFromUser)")
            if presenceType == "available" 
                delegate.buddyWentOnline("\(presenceFromUser)@gmail.com")
             else if presenceType == "unavailable" 
                delegate.buddyWentOffline("\(presenceFromUser)@gmail.com")
            
        
    

    func xmppRoster(_ sender: XMPPRoster!, didReceiveRosterItem item: DDXMLElement!) 
        print("Did receive Roster item")
    

【问题讨论】:

【参考方案1】:

最后我设法解决了这个问题,我真的很惊讶使用托管在 Amazon 上的 Ejabberd 服务器来实现聊天应用程序。

问题:

1.当我运行我的应用程序时,它没有连接?

答案:证书问题(服务器 - 客户端证书握手解决问题)

2.无法获取在线好友? 答:我使用 Adium 让所有用户在线,然后运行我的应用程序,它就像一个魅力。

这个应用程序对我来说很棒。 如果任何人对聊天有任何问题,请随时发表评论,我期待提供帮助。谢谢

【讨论】:

嗨@Shobhakar 我正在编写一个聊天应用程序,并且想知道一些事情,因为我对xmpp 不太熟悉。我需要创建服务器还是可以使用 jabber?你能推荐一个好的框架/库来快速使用吗?您遇到的任何教程对您有帮助吗?非常感谢您提供的任何信息或帮助。九月 您可以使用 ejaberd 服务器,远程访问需要在 Amazon 上托管 ejaberd,否则。检查 Swift 演示或 ping 我 Skype 你好肖巴卡。什么是服务器 - 客户端证书握手解决问题?这个怎么用?

以上是关于将 iOS 应用程序连接到 Amazon 上托管的 Ejabberd 服务器的主要内容,如果未能解决你的问题,请参考以下文章

当两者都连接到同一个热点时,客户端无法访问服务器上托管的网站

HTTP 连接在 Amazon EC2 上托管的 nodejs 应用程序中过早终止

使用NGINX在端口80上为使用虚拟主机的Amazon EC2上托管的域的node.js应用程序提供HTTP流量

从 docker 连接到 office365 SMTP 时出现异常

如何将客户端的正确 IP 地址获取到 Heroku 上托管的 Node socket.io 应用程序中?

TomCat上托管的Play项目中的随机错误:异常ClientAbortException:null