如何用Ionic与Strophe.js实现XMPP注册系统?
Ionic 3 + Strophe.js + eJabberd 注册功能实现指南
嘿,恭喜你已经搞定了XMPP登录功能!作为新手,注册功能确实容易摸不着头绪,不过别担心——Strophe.js内置了注册相关的API,配合eJabberd的正确配置,咱们很快就能搞定。
首先要确认你的eJabberd服务器已经开启了注册权限:
- 打开eJabberd的配置文件
ejabberd.yml - 找到
access_rules部分,确保register规则设置为allow all - 找到
modules下的mod_register,确保allow_register: true - 重启eJabberd服务
接下来咱们一步步修改代码实现注册功能:
1. 扩展XMPPService,添加注册方法
在你的xmpp-service.ts中,新增注册相关的方法和状态处理:
import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { Events } from 'ionic-angular'; import { Strophe } from 'strophe.js'; declare let Strophe: any; export class Message { id: String; senderId: String; text: String; time: String; } @Injectable() export class XMPPService { private dismissObserver: any; public dismiss: any; private BOSH_SERVICE: string = "localhost:5280/http-bind/"; private CONFERENCE_SERVICE: string = "conference.localhost"; private connection: Strophe.Connection; private roomName: string = ""; constructor(public events: Events) { this.dismissObserver = null; this.dismiss = Observable.create(observer => { this.dismissObserver = observer; }); } // 原有的login方法保持不变 login(jid, host, pass) { this.connection = new Strophe.Connection(this.BOSH_SERVICE, { 'keepalive': true }); this.connection.connect(jid + '@' + host, pass, (status) => { this.onConnect(status); }); } // 新增注册方法 signup(jid, host, pass) { this.connection = new Strophe.Connection(this.BOSH_SERVICE); // 初始化注册流程 this.connection.register.connect(host, (status) => { this.onRegister(status, jid, pass); }); } // 注册状态处理回调 private onRegister(status: number, jid: string, pass: string) { switch (status) { case Strophe.Status.REGISTER: // 服务器请求注册信息,填充用户名和密码 this.connection.register.fields.username = jid; this.connection.register.fields.password = pass; // 提交注册请求 this.connection.register.submit(); break; case Strophe.Status.REGISTERED: console.log('[Registration] 注册成功!'); this.dismissObserver.next("signup-success"); // 可选:注册成功后自动登录 // this.login(jid, this.connection.domain, pass); break; case Strophe.Status.REGIFAIL: console.log('[Registration] 注册失败:用户名已存在'); this.dismissObserver.next("signup-fail-exists"); break; case Strophe.Status.CONNFAIL: console.log('[Registration] 连接服务器失败'); this.dismissObserver.next("signup-fail-connection"); break; case Strophe.Status.DISCONNECTED: console.log('[Registration] 连接断开'); break; default: console.log('[Registration] 未知状态:', status); break; } } // 原有的logout、onConnect等方法保持不变 logout() { this.connection.options.sync = true; this.connection.flush(); this.connection.disconnect(); } onConnect(status) { var self = this; switch (status) { case Strophe.Status.CONNECTED: console.log('[Connection] Strophe is Connected'); this.connection.addHandler((msg) => { self.onMessage(msg); return true; }, null, 'message', null, null, null); this.connection.addHandler((stanza) => { self.onSubscriptionRequest(stanza) }, null, "presence", "subscribe"); this.dismissObserver.next("login"); break; case Strophe.Status.ATTACHED: console.log('[Connection] Strophe is Attached'); break; case Strophe.Status.DISCONNECTED: console.log('[Connection] Strophe is Disconnected'); this.dismissObserver.next("logout"); break; case Strophe.Status.AUTHFAIL: console.log('[Connection] Strophe is Authentication failed'); break; case Strophe.Status.CONNECTING: console.log('[Connection] Strophe is Connecting'); break; case Strophe.Status.DISCONNECTING: console.log('[Connection] Strophe is Disconnecting'); break; case Strophe.Status.AUTHENTICATING: console.log('[Connection] Strophe is Authenticating'); break; case Strophe.Status.ERROR: case Strophe.Status.CONNFAIL: console.log('[Connection] Failed (' + status + ')'); break; default: console.log('[Connection] Unknown status received:', status); break; } }; // 补充你原有的消息处理方法(如果未实现) private onMessage(msg: any) { // 消息处理逻辑 } private onSubscriptionRequest(stanza: any) { // 订阅请求处理逻辑 } }
2. 创建注册页面(SignupPage)
signup.ts
import { Component } from '@angular/core'; import { IonicPage, NavController, ToastController } from 'ionic-angular'; import { XMPPService } from '../../app/xmpp.service'; import { LoginPage } from '../login/login'; @IonicPage() @Component({ selector: 'page-signup', templateUrl: 'signup.html', }) export class SignupPage { private jid: string = ""; private host: string = "localhost"; private password: string = ""; private confirmPassword: string = ""; constructor( public navCtrl: NavController, public toastCtrl: ToastController, public xmppService: XMPPService ) { // 监听注册结果事件 this.xmppService.dismiss.subscribe((event: string) => { this.handleSignupEvent(event); }); } signup() { // 前端基础校验 if (this.password !== this.confirmPassword) { this.showToast("两次输入的密码不一致"); return; } if (!this.jid || !this.password) { this.showToast("请填写完整的用户名和密码"); return; } // 调用注册服务 this.xmppService.signup(this.jid, this.host, this.password); } private handleSignupEvent(event: string) { switch (event) { case "signup-success": this.showToast("注册成功,即将跳转到登录页面"); setTimeout(() => { this.navCtrl.push(LoginPage); }, 1500); break; case "signup-fail-exists": this.showToast("用户名已存在,请更换"); break; case "signup-fail-connection": this.showToast("连接服务器失败,请检查服务器状态"); break; } } private showToast(message: string) { let toast = this.toastCtrl.create({ message: message, duration: 2000, position: 'bottom' }); toast.present(); } goToLogin() { this.navCtrl.push(LoginPage); } }
signup.html
<ion-header> <ion-navbar> <ion-title>注册账号</ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-list> <ion-item> <ion-label floating>用户名</ion-label> <ion-input type="text" [(ngModel)]="jid"></ion-input> </ion-item> <ion-item> <ion-label floating>密码</ion-label> <ion-input type="password" [(ngModel)]="password"></ion-input> </ion-item> <ion-item> <ion-label floating>确认密码</ion-label> <ion-input type="password" [(ngModel)]="confirmPassword"></ion-input> </ion-item> </ion-list> <button ion-button block (click)="signup()" [disabled]="!jid || !password || !confirmPassword"> 注册 </button> <button ion-button block clear (click)="goToLogin()"> 已有账号?去登录 </button> </ion-content>
3. 关键说明
- Strophe注册流程:
connection.register.connect()触发注册流程,收到REGISTER状态时,需填充账号密码并调用submit()提交请求 - 状态处理:覆盖常见注册状态,给用户清晰的操作反馈
- eJabberd配置:必须确保服务器允许注册,否则所有请求都会被拒绝
- 错误扩展:实际项目中可根据eJabberd返回的错误码,添加密码强度校验等更细致的处理逻辑
最后别忘了在项目路由配置中注册SignupPage哦!
内容的提问来源于stack exchange,提问作者H. Nzau
相关产品推荐
相关产品推荐

