1
回复

iOS环信聊天界面在view上怎么实现? iOS,环信聊天界面

berylwang 回复了问题 • 2 人关注 • 443 次浏览 • 2019-03-11 18:45 • 来自相关话题

1
回复

环信web端登录报错 failed: Data frame received after close 环信_WebIM 环信

lizg 回复了问题 • 2 人关注 • 472 次浏览 • 2019-03-11 18:00 • 来自相关话题

1
回复

android视频打开问题 环信_Android 视频

lizg 回复了问题 • 2 人关注 • 474 次浏览 • 2019-03-11 17:59 • 来自相关话题

1
回复

使用easeui集成注册时提示unknown source 环信_Android

lizg 回复了问题 • 2 人关注 • 419 次浏览 • 2019-03-11 17:49 • 来自相关话题

1
回复

Android 群邀请人,收不到回调监听。 环信_Android 有关于回调的问题

lizg 回复了问题 • 2 人关注 • 501 次浏览 • 2019-03-11 17:29 • 来自相关话题

1
回复

【Android】3.5.3版本SDK,无法初始化 环信_Android

lizg 回复了问题 • 2 人关注 • 534 次浏览 • 2019-03-11 17:23 • 来自相关话题

1
回复

关于iOS 环信demo3.0 报错 环信_iOS

lizg 回复了问题 • 2 人关注 • 526 次浏览 • 2019-03-11 17:25 • 来自相关话题

0
评论

React Native调用原生Android/iOS代码方案并实现拨号功能 iOS andorid react native IT大前端

serge 发表了文章 • 259 次浏览 • 2019-03-09 23:11 • 来自相关话题

一 前言

由于前几个月公司2.0项目开发技术选型为React Native,技术部相关人员开始学习React Native相关的技术,笔者是一名Android开发者,下文所描述的React Native调用Android/iOS模块中关于iOS的部分如有误的地方,请指出。为了让从Android或iOS学习React Native的同志更加清楚的了解另一移动端,笔者尽可能写的详细点。

二 效果

下面两张图分别为iOS和Android上效果图,其中iOS效果图中点击电话号码会打印log,并不会调起iOS拨号界面,因为iOS模拟器不支持此功能,所以要想看效果只能用真机查看。这里打印log是为了证明React Native成功调起了原生iOS模块功能。





 





 
 
三 实现方案

关于调用拨号功能以及调用浏览器、短信、邮箱等功能,可有两种实现方案。

一种是按照React Native提供的调用原生的过程方案来调用,这种适合大部分React Native调用原生功能的需求,掌握这种后,基本以后再有调用原生需求即可按照此过程方案解决,此文也会选用这种方案进行描述。

另一种是React Native帮我们封装的Linking模块可以实现这类的需求,这种相比上一种来说相对简单,主要适用于调用原生的电话、短信、邮箱、浏览器等功能。

四 实现原生Android模块

1.在自己新建的Reacat Native项目中android/app/src/main/java/xxx(项目包名)/ 目录下(为了和其他文件分离,笔者又在此目录下新建一个native文件夹),需要新建一个java类文件,例如文件名为CallPhoneModule.java,这个java类一定要继承RN提供的ReactContextBaseJavaModule抽象类,然后实现其构造函数,其中的参数要为ReactApplicationContext reactContext。
 
public class CallPhoneModule extends ReactContextBaseJavaModule {
public CallPhoneModule(ReactApplicationContext reactContext) {
super(reactContext);
}
}
 
2.然后实现NativeModule中定义的getName()方法,返回一个String类型字符串,这个返回结果将要在JavaScript中使用,例如返回“CallPhoneModule”,则可以在JavaScript中通过React.NativeModules.CallPhoneModule调用。
 
注意,如果返回的字符串中有RCT前缀,则会自动移除RCT前缀。例如返回“RCTCallPhoneModule”,则在JavaScript中依然可以通过React.NativeModules.CallPhoneModule调用。CallPhoneModule继承ReactContextBaseJavaModule,ReactContextBaseJavaModule继承BaseJavaModule,BaseJavaModule实现了NativeModule接口,这是CallPhoneModule与NativeModule的关系。 
@Override
public String getName() {
return "CallPhoneModule";
}
 
3.然后在CallPhoneModule类中写一个方法,这个方法提供给JavaScript调用,例如方法名为callPhone,里面传递String类型参数(非必须),特别的这个方法要使用@ReactMethod注解,以及返回类型必须为void。然后在callPhone方法中写入要实现的功能,这里写入了拨号功能的实现。
 
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneString));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.reactContext.startActivity(intent);
CallPhoneModule.java文件的全部代码如下:
package com.zhuku02;

import android.content.Intent;
import android.net.Uri;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.lang.String;

public class CallPhoneModule extends ReactContextBaseJavaModule {

public ReactApplicationContext reactContext;

public CallPhoneModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}

@ReactMethod
public void callPhone(String phoneString) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneString));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.reactContext.startActivity(intent);
}

@Override
public String getName() {
return "CallPhoneModule";
}
}
4.新建一个java类文件,例如文件名为CallPhoneReactPackage.java,这个类必须实现ReactPackage接口,然后实现createViewManagers、createNativeModules两个方法,特别的要在createNativeModules方法的返回值中add进刚才新建的CallPhoneModule类。

CallPhoneReactPackage.java全部代码如下:
package com.zhuku02;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.zhuku02.CallPhoneModule;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CallPhoneReactPackage implements ReactPackage {

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}

@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();

modules.add(new CallPhoneModule(reactContext));

return modules;
}
}
5.最后在MainApplication.java文件中的getPackages方法中加上刚才新建的CallPhoneReactPackage类。至此,原生Android模块书写完毕。关于JavaScript调用原生Android模块代码会在文末和调用原生iOS一起写出。

修改后的MainApplication.java文件代码如下:
package com.zhuku02;

import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

import com.zhuku02.CallPhoneReactPackage;

import java.util.Arrays;
import java.util.List;


public class MainApplication extends Application implements ReactApplication {

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}

@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CallPhoneReactPackage()
);
}
};

@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}

@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
 
五 实现原生iOS模块

1.在自己新建的Reacat Native项目中ios/xxx(项目包名)/ 目录下,需要新建一个后缀为m和一个后缀为h的文件。为了和其他文件分离以及和Android保持一致,笔者又在此目录下新建一个native文件夹。
 
在Xcode的此文件夹上右键New File,然后在弹出的页面中Cocoa Touch Class选项输入文件名,这样会建立出相同文件名的m和h文件。如果New File时,分别选择Objective-C File和Header File,则这两个文件名要相同。例如文件名称为CallPhoneModuleIos。

2.在CallPhoneModuleIos.h文件中,类要实现RN提供的RCTBridgeModule协议。RCT是ReaCT的缩写,React Native中Object-C相关的命名均以RCT开头。
 
RCTBridgeModule是定义好的protocol,实现该协议的类,会自动注册到Object-C对应的Bridge中。Object-C Bridge上层负责与Object-C通信,下层负责和JavaScript Bridge通信,而JavaScript Bridge负责和JavaScript通信。这样,通过Object-C Bridge和JavaScript Bridge就可以实现JavaScript和Object-C的相互调用。

CallPhoneModuleIos.h文件如下:
#import <UIKit/UIKit.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTLog.h>

@interface CallPhoneModuleIos : NSObject <RCTBridgeModule>

@end
3.CallPhoneModuleIos.m文件中,类需要包含RCT_EXPORT_MODULE()宏,作用是自动注册一个module。这个宏可以添加一个参数,用来指定在JavaScript调用这个模块的名字,类似于上文中说的getName()方法。如果不添加这个参数,则默认就是这个类的名字。

4.然后需要在此类中写一个方法,提供给RN调用,方法通过RCT_EXPORT_METHOD()宏来实现。
RCT_EXPORT_METHOD(callPhone: (NSString *)phone){
NSLog(@"======%@",phone);
}
CallPhoneModuleIos.m完整代码:
#import "CallPhoneModuleIos.h"
#import <Foundation/Foundation.h>

@implementation CallPhoneModuleIos

RCT_EXPORT_MODULE(CallPhoneModuleIos);

RCT_EXPORT_METHOD(callPhone: (NSString *)phone){

NSLog(@"======%@",phone);
//去掉注释,下面代码就是实现拨号功能代码,但还未真机测试
// NSMutableString * str = [[NSMutableString alloc] initWithFormat:@"telprompt://%@",phone];
// [[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];

}

// -(dispath_queue_t)methodQueue{
// return dispath_get_main_queue();
// }

@end
至此,则原生iOS代码书写完成,现在即将开始调用。

六 React Native调用Android、iOS原生模块

为了在JavaScript端同时访问Android、iOS原生模块更加方便,笔者把原生模块的调用封装在一个JavaScript文件中,例如文件名为CallPhone.js,这样在需要调用的地方直接调用此JavaScript文件既可,同时在此文件中,处理好Android、iOS、Web(若有)的分别调用。
import {Platform, NativeModules} from 'react-native';

var module = null;
if (Platform.OS == 'ios') {
module = NativeModules.CallPhoneModuleIos;
} else if (Platform.OS == 'android') {
module = NativeModules.CallPhoneModule;
} else if (Platform.OS == 'web') {
//暂未实现web功能
}
export default module;
然后在JavaScript文件中这样调用:
import CallPhone from '../../native/CallPhone';
CallPhone.callPhone('40077731xx');
到这里,整篇文章就结束了,疑问、建议或者指教欢迎讨论。

七 参考资料

native-modules-ios (https://facebook.github.io/rea ... s.html)
native-modules-android (https://facebook.github.io/rea ... d.html) 






微信公众号:IT大前端
关注可了解更多的大前端领域技术 查看全部
一 前言

由于前几个月公司2.0项目开发技术选型为React Native,技术部相关人员开始学习React Native相关的技术,笔者是一名Android开发者,下文所描述的React Native调用Android/iOS模块中关于iOS的部分如有误的地方,请指出。为了让从Android或iOS学习React Native的同志更加清楚的了解另一移动端,笔者尽可能写的详细点。

二 效果

下面两张图分别为iOS和Android上效果图,其中iOS效果图中点击电话号码会打印log,并不会调起iOS拨号界面,因为iOS模拟器不支持此功能,所以要想看效果只能用真机查看。这里打印log是为了证明React Native成功调起了原生iOS模块功能。

640.gif

 

640_(1).gif

 
 
三 实现方案

关于调用拨号功能以及调用浏览器、短信、邮箱等功能,可有两种实现方案。

一种是按照React Native提供的调用原生的过程方案来调用,这种适合大部分React Native调用原生功能的需求,掌握这种后,基本以后再有调用原生需求即可按照此过程方案解决,此文也会选用这种方案进行描述。

另一种是React Native帮我们封装的Linking模块可以实现这类的需求,这种相比上一种来说相对简单,主要适用于调用原生的电话、短信、邮箱、浏览器等功能。

四 实现原生Android模块

1.在自己新建的Reacat Native项目中android/app/src/main/java/xxx(项目包名)/ 目录下(为了和其他文件分离,笔者又在此目录下新建一个native文件夹),需要新建一个java类文件,例如文件名为CallPhoneModule.java,这个java类一定要继承RN提供的ReactContextBaseJavaModule抽象类,然后实现其构造函数,其中的参数要为ReactApplicationContext reactContext。
 
public class CallPhoneModule extends ReactContextBaseJavaModule {
public CallPhoneModule(ReactApplicationContext reactContext) {
super(reactContext);
}
}

 
2.然后实现NativeModule中定义的getName()方法,返回一个String类型字符串,这个返回结果将要在JavaScript中使用,例如返回“CallPhoneModule”,则可以在JavaScript中通过React.NativeModules.CallPhoneModule调用。
 
注意,如果返回的字符串中有RCT前缀,则会自动移除RCT前缀。例如返回“RCTCallPhoneModule”,则在JavaScript中依然可以通过React.NativeModules.CallPhoneModule调用。CallPhoneModule继承ReactContextBaseJavaModule,ReactContextBaseJavaModule继承BaseJavaModule,BaseJavaModule实现了NativeModule接口,这是CallPhoneModule与NativeModule的关系。 
@Override
public String getName() {
return "CallPhoneModule";
}

 
3.然后在CallPhoneModule类中写一个方法,这个方法提供给JavaScript调用,例如方法名为callPhone,里面传递String类型参数(非必须),特别的这个方法要使用@ReactMethod注解,以及返回类型必须为void。然后在callPhone方法中写入要实现的功能,这里写入了拨号功能的实现。
 
Intent intent = new Intent(Intent.ACTION_DIAL,  Uri.parse("tel:" + phoneString));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.reactContext.startActivity(intent);

CallPhoneModule.java文件的全部代码如下:
package com.zhuku02;

import android.content.Intent;
import android.net.Uri;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.lang.String;

public class CallPhoneModule extends ReactContextBaseJavaModule {

public ReactApplicationContext reactContext;

public CallPhoneModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}

@ReactMethod
public void callPhone(String phoneString) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneString));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.reactContext.startActivity(intent);
}

@Override
public String getName() {
return "CallPhoneModule";
}
}

4.新建一个java类文件,例如文件名为CallPhoneReactPackage.java,这个类必须实现ReactPackage接口,然后实现createViewManagers、createNativeModules两个方法,特别的要在createNativeModules方法的返回值中add进刚才新建的CallPhoneModule类。

CallPhoneReactPackage.java全部代码如下:
package com.zhuku02;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.zhuku02.CallPhoneModule;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CallPhoneReactPackage implements ReactPackage {

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}

@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();

modules.add(new CallPhoneModule(reactContext));

return modules;
}
}

5.最后在MainApplication.java文件中的getPackages方法中加上刚才新建的CallPhoneReactPackage类。至此,原生Android模块书写完毕。关于JavaScript调用原生Android模块代码会在文末和调用原生iOS一起写出。

修改后的MainApplication.java文件代码如下:
package com.zhuku02;

import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

import com.zhuku02.CallPhoneReactPackage;

import java.util.Arrays;
import java.util.List;


public class MainApplication extends Application implements ReactApplication {

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}

@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CallPhoneReactPackage()
);
}
};

@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}

@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}

 
五 实现原生iOS模块

1.在自己新建的Reacat Native项目中ios/xxx(项目包名)/ 目录下,需要新建一个后缀为m和一个后缀为h的文件。为了和其他文件分离以及和Android保持一致,笔者又在此目录下新建一个native文件夹。
 
在Xcode的此文件夹上右键New File,然后在弹出的页面中Cocoa Touch Class选项输入文件名,这样会建立出相同文件名的m和h文件。如果New File时,分别选择Objective-C File和Header File,则这两个文件名要相同。例如文件名称为CallPhoneModuleIos。

2.在CallPhoneModuleIos.h文件中,类要实现RN提供的RCTBridgeModule协议。RCT是ReaCT的缩写,React Native中Object-C相关的命名均以RCT开头。
 
RCTBridgeModule是定义好的protocol,实现该协议的类,会自动注册到Object-C对应的Bridge中。Object-C Bridge上层负责与Object-C通信,下层负责和JavaScript Bridge通信,而JavaScript Bridge负责和JavaScript通信。这样,通过Object-C Bridge和JavaScript Bridge就可以实现JavaScript和Object-C的相互调用。

CallPhoneModuleIos.h文件如下:
#import <UIKit/UIKit.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTLog.h>

@interface CallPhoneModuleIos : NSObject <RCTBridgeModule>

@end

3.CallPhoneModuleIos.m文件中,类需要包含RCT_EXPORT_MODULE()宏,作用是自动注册一个module。这个宏可以添加一个参数,用来指定在JavaScript调用这个模块的名字,类似于上文中说的getName()方法。如果不添加这个参数,则默认就是这个类的名字。

4.然后需要在此类中写一个方法,提供给RN调用,方法通过RCT_EXPORT_METHOD()宏来实现。
RCT_EXPORT_METHOD(callPhone: (NSString *)phone){
NSLog(@"======%@",phone);
}

CallPhoneModuleIos.m完整代码:
#import "CallPhoneModuleIos.h"
#import <Foundation/Foundation.h>

@implementation CallPhoneModuleIos

RCT_EXPORT_MODULE(CallPhoneModuleIos);

RCT_EXPORT_METHOD(callPhone: (NSString *)phone){

NSLog(@"======%@",phone);
//去掉注释,下面代码就是实现拨号功能代码,但还未真机测试
// NSMutableString * str = [[NSMutableString alloc] initWithFormat:@"telprompt://%@",phone];
// [[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];

}

// -(dispath_queue_t)methodQueue{
// return dispath_get_main_queue();
// }

@end

至此,则原生iOS代码书写完成,现在即将开始调用。

六 React Native调用Android、iOS原生模块

为了在JavaScript端同时访问Android、iOS原生模块更加方便,笔者把原生模块的调用封装在一个JavaScript文件中,例如文件名为CallPhone.js,这样在需要调用的地方直接调用此JavaScript文件既可,同时在此文件中,处理好Android、iOS、Web(若有)的分别调用。
import {Platform, NativeModules} from 'react-native';

var module = null;
if (Platform.OS == 'ios') {
module = NativeModules.CallPhoneModuleIos;
} else if (Platform.OS == 'android') {
module = NativeModules.CallPhoneModule;
} else if (Platform.OS == 'web') {
//暂未实现web功能
}
export default module;

然后在JavaScript文件中这样调用:
import CallPhone from '../../native/CallPhone';
CallPhone.callPhone('40077731xx');

到这里,整篇文章就结束了,疑问、建议或者指教欢迎讨论。

七 参考资料

native-modules-ios (https://facebook.github.io/rea ... s.html)
native-modules-android (https://facebook.github.io/rea ... d.html) 


qrcode_for_gh_08bfa7313fb2_258.jpg

微信公众号:IT大前端
关注可了解更多的大前端领域技术
1
最佳

环信登录提示404 环信web 环信

beyond 回复了问题 • 2 人关注 • 473 次浏览 • 2019-03-08 10:25 • 来自相关话题

1
评论

EaseUI 3.5.3 DexArchiveMergerException easeui集成报错 EaseUI

今天我没空 发表了文章 • 277 次浏览 • 2019-03-05 16:17 • 来自相关话题

集成easeui3.5.3报错
集成easeui3.5.3报错
1
评论

【活动推荐】2019安卓巴士千人开发者大会-NEW●无界

beyond 发表了文章 • 3611 次浏览 • 2019-03-05 14:40 • 来自相关话题

本次将邀请到BAT等知名互联网公司的16位优秀演讲嘉宾坐镇,内容上除了主会场全天的Android技术干货分享,分会场还将覆盖到大数据、机器学习、跨平台开发以及小程序等方向内容。
三人行两人免单团购超便宜报名速戳https://www.hdb.com/dis/htn3yi6fpo
活动时间:2019年4月20号
活动地点:深圳南山区圣淘沙酒店
 
*入现场群说明:

购票成功后,请添加安卓巴士官方微信号 shzsbgbs ,备注【开发者大会】通过后提供购票成功截图,小编邀请您进入420开发者大会现场群。

备注【拼团】邀请您进入拼团群,和小伙伴一起享受超低团购价。

*付费说明:

本次活动经费用于场租、设备、物料、礼品、嘉宾交通住宿费等。

*退款说明:

由于本活动各项资源需提前采购,一经售出不接受退款,请确认后购买。 
 















  查看全部
   本次将邀请到BAT等知名互联网公司的16位优秀演讲嘉宾坐镇,内容上除了主会场全天的Android技术干货分享,分会场还将覆盖到大数据、机器学习、跨平台开发以及小程序等方向内容。

三人行两人免单团购超便宜报名速戳https://www.hdb.com/dis/htn3yi6fpo
活动时间:2019年4月20号
活动地点:深圳南山区圣淘沙酒店
 
*入现场群说明:

购票成功后,请添加安卓巴士官方微信号 shzsbgbs ,备注【开发者大会】通过后提供购票成功截图,小编邀请您进入420开发者大会现场群。

备注【拼团】邀请您进入拼团群,和小伙伴一起享受超低团购价。

*付费说明:

本次活动经费用于场租、设备、物料、礼品、嘉宾交通住宿费等。

*退款说明:

由于本活动各项资源需提前采购,一经售出不接受退款,请确认后购买。 
 

41551673499360_article4_58412.jpg


41551673130966_article4_57367.jpg


微信图片_20190305183217.jpg

 
0
评论

WIFI 考勤打卡 浅析 WIFI Android

serge 发表了文章 • 310 次浏览 • 2019-03-04 22:11 • 来自相关话题

一、背景

最近产品部提出了在WEB端设置wifi考勤打卡新需求,根据管理员设置的wifi相关信息(主要是WIFI名称和MAC地址),员工用户利用移动端相连接的wifi进行wifi考勤打卡。

二、名词术语解释

下面的理解全是建立在无线路由器的基础上。如有错误请指出。

1、SS

SS(Service set)即服务集,是无线局域网中的一个术语,用以描述802.11无线网络的构成单位(一组互相有联系的无线设备),使用服务集标识符(SSID)作为识别。

可以分为独立基本服务集(IBSS)、基本服务集(BSS)和扩展服务集(ESS)三类。其中IBSS属于对等拓扑模式(又称Ad-Hoc模式、无线随意网络),而BSS和ESS属于基础架构模式。这些拓扑是原始的802.11规范中定义的,其他的如网桥、中继器等则是属于特定厂商的扩展或者WDS的拓扑模式。

2、SSID

SSID(Service Set Identifier)即服务集标识符,是一个或一组基础架构模式无线网络的标识,依照标识方式又可细分为两种:
基本服务集标识符(BSSID),表示的是AP的数据链路层的MAC地址。
扩展服务集标识符(ESSID),一个最长32字节区分大小写的字符串,ESSID标识与SSID相同的网络。术语SSID最常用。
在此可以理解为无线路由器发射的某个wifi的名称。(SSID=name of network)

3、BSS

BSS(Basic Service Set)即基本服务集,是一组能在PHY层相互通信的所有站。每个BSS都有一个称为BSSID的标识(ID),它是服务于BSS的接入点的MAC地址。
用在无线路由器发射出的wifi上可以这样理解:某一个无线路由器发射出的wifi信号所覆盖的范围可视为BSS。





 
4、BSSID

BSSID(Basic Service Set Identifier)即基本服务集标识符。

在上面的基础上可以这样理解:对某一个BSS基本服务集的唯一标识。例如,某无线路由器发射了一个名称为A的wifi热点,同一区域另一个无线路由器也发出了一个名称为A的wifi热点,当手机连接A热点时,如何辨别连接的是由哪一个路由器发射的wifi呢?

这时候就要用到BSSID了。一般情况下BSSID可以理解为无线路由器的MAC地址,通过查看手机连接wifi的MAC地址即可知道连接的是哪一个路由。(BSSID=AP MAC address)
其实准确来说手机得到的BSSID并不是路由器的基准(出厂)MAC地址。

例如,笔者公司的某款无线路由器B的出厂MAC地址为 XX:XX:XX:XX:XX:F1,当手机连接此wifi查看mac地址时发现是XX:XX:XX:XX:XX:F2,或者是XX:XX:XX:XX:XX:F3。

5、ESS ESSID

ESS(Extended Service Set )即扩展的基本服务集。
ESSID(Extended Service Set Identifier)即扩展的基本服务集标识符。
BSS+BSS+BSS+BSS+…=ESS。ESS为多个BSS的集合。ESS使用指定的ESSID作识别。

通过将多个BSS比邻安置,可以扩展网络的范围,如果这些BSS通过各种分布系统互联(无论是有线的还是无线的),拥有一致的ESSID,并且对于逻辑链路控制层来说可以认为是一个BSS的话,那么这些BSS可以被统一为一个ESS。

在同一个ESS中的不同BSS之间切换的过程称为漫游。一般而言,一个ESS中的BSS都会使用相同的SSID和安全机制以提供接近于无缝漫游的可能。两个BSS之间通常有15%左右的重叠范围来保证漫游时信号不会长时间丢失,并且设置在不同频段来防止相互干扰。





 
6、MAC

MAC地址采用十六进制数表示,共六个字节(48位)。(XX:XX:XX:XX:XX:XX )其中,前三个字节是由IEEE的注册管理机构RA负责给不同厂家分配的代码(高位24位),也称为“编制上唯一的标识符”(Organizationally Unique Identifier),后三个字节(低位24位)由各厂家自行指派给生产的适配器接口,称为扩展标识符(唯一性)。

三、历程

当产品部提出wifi考勤打卡需求时,普遍认为一个路由器有一个mac地址,手机连接wifi可以根据mac地址等信息进行打卡。当我们用多个手机连接公司名称为A(SSID)的wifi时,发现手机上展示的mac地址并不是一致的,这个就尴尬了,打翻了原有理念。
然后发现我们公司共有五个无线路由器,wifi名称都是A。哦,这时候才感觉到原来以前的知识还是靠谱的,可能是多个手机具体连接的路由器不是同一个。

然后把五个路由器wifi热点名称改为A、B、C、D、E,多个手机连接A热点时,发现手机得到的mac地址是一致的,到这里可以得出的结论是手机连接同一个wifi热点得到的mac地址是一致的。但是…..又尴尬了。

当多款手机连接B热点时,发现又出现了不一致的mac地址,查找原因发现,原来B无线路由器中可以设置2.4G Hz和5G Hz两个不同频段的wifi热点。B路由器中默认是开启2.4G Hz和5G Hz频段的wifi热点,并且wifi名称(SSID)是同一个。经过检查还有个问题是B路由器的出厂mac地址和手机连接得到的mac地址不一致。

例如上面举得例子:笔者公司的某款无线路由器B的出厂MAC地址为 XX:XX:XX:XX:XX:F1,当手机连接此wifi查看mac地址时发现是XX:XX:XX:XX:XX:F2,另一款手机连接时是XX:XX:XX:XX:XX:F3。由此可得出的结论是,路由器有一个基准(出厂)mac地址,然后发射出wifi的mac在基准mac地址上按照一定的算法进行变动,具体的变动算法不清楚,有清楚的请告知我,非常感谢。

另外还有一个问题是,C路由器设备后面所写的出厂说明mac地址是XX:XX:XX:XX:XX:56,但是通过路由器后台看到的出厂mac地址是XX:XX:XX:XX:XX:57,手机连接后得到的mac地址是XX:XX:XX:XX:XX:56。这就尴尬了,是厂家写错了还是根据特定的算法算的?

除了根据wifi设备分析外,我们也对具有wifi考勤打卡功能的软件进行了分析。比如现在比较火爆的由阿里团队研发的钉钉,以及纷享销客APP,在Android端,他们的处理都是获取周围wifi信息(并不是当前手机连接的wifi)进行打卡。在iOS端,他们的处理都是根据当前手机连接的wifi信息进行打卡。据iOS同事说,iOS获取周围wifi信息需要申请此功能,并最低支持版本是iOS 9。另外据可靠消息,分享逍客对mac地址的处理也是通过忽略低4位进行匹配。

四、结论

经过上述分析,手机获取的无线路由器MAC地址的低4位是变化的。那我们实现这个需求时,除了匹配虚拟位置、手机信息、wifi相关等其他信息外,只针对mac地址,我们可以忽略mac地址的低4位来做匹配。

五、参考资料

http://www.juniper.net/documentation/en_US/junos-space-apps12.3/network-director/topics/concept/wireless-ssid-bssid-essid.html 






微信公众号:IT大前端
关注可了解更多的大前端领域技术 查看全部
一、背景

最近产品部提出了在WEB端设置wifi考勤打卡新需求,根据管理员设置的wifi相关信息(主要是WIFI名称和MAC地址),员工用户利用移动端相连接的wifi进行wifi考勤打卡。

二、名词术语解释

下面的理解全是建立在无线路由器的基础上。如有错误请指出。

1、SS

SS(Service set)即服务集,是无线局域网中的一个术语,用以描述802.11无线网络的构成单位(一组互相有联系的无线设备),使用服务集标识符(SSID)作为识别。

可以分为独立基本服务集(IBSS)、基本服务集(BSS)和扩展服务集(ESS)三类。其中IBSS属于对等拓扑模式(又称Ad-Hoc模式、无线随意网络),而BSS和ESS属于基础架构模式。这些拓扑是原始的802.11规范中定义的,其他的如网桥、中继器等则是属于特定厂商的扩展或者WDS的拓扑模式。

2、SSID

SSID(Service Set Identifier)即服务集标识符,是一个或一组基础架构模式无线网络的标识,依照标识方式又可细分为两种:
基本服务集标识符(BSSID),表示的是AP的数据链路层的MAC地址。
扩展服务集标识符(ESSID),一个最长32字节区分大小写的字符串,ESSID标识与SSID相同的网络。术语SSID最常用。
在此可以理解为无线路由器发射的某个wifi的名称。(SSID=name of network)

3、BSS

BSS(Basic Service Set)即基本服务集,是一组能在PHY层相互通信的所有站。每个BSS都有一个称为BSSID的标识(ID),它是服务于BSS的接入点的MAC地址。
用在无线路由器发射出的wifi上可以这样理解:某一个无线路由器发射出的wifi信号所覆盖的范围可视为BSS。

WechatIMG363.jpeg

 
4、BSSID

BSSID(Basic Service Set Identifier)即基本服务集标识符。

在上面的基础上可以这样理解:对某一个BSS基本服务集的唯一标识。例如,某无线路由器发射了一个名称为A的wifi热点,同一区域另一个无线路由器也发出了一个名称为A的wifi热点,当手机连接A热点时,如何辨别连接的是由哪一个路由器发射的wifi呢?

这时候就要用到BSSID了。一般情况下BSSID可以理解为无线路由器的MAC地址,通过查看手机连接wifi的MAC地址即可知道连接的是哪一个路由。(BSSID=AP MAC address)
其实准确来说手机得到的BSSID并不是路由器的基准(出厂)MAC地址。

例如,笔者公司的某款无线路由器B的出厂MAC地址为 XX:XX:XX:XX:XX:F1,当手机连接此wifi查看mac地址时发现是XX:XX:XX:XX:XX:F2,或者是XX:XX:XX:XX:XX:F3。

5、ESS ESSID

ESS(Extended Service Set )即扩展的基本服务集。
ESSID(Extended Service Set Identifier)即扩展的基本服务集标识符。
BSS+BSS+BSS+BSS+…=ESS。ESS为多个BSS的集合。ESS使用指定的ESSID作识别。

通过将多个BSS比邻安置,可以扩展网络的范围,如果这些BSS通过各种分布系统互联(无论是有线的还是无线的),拥有一致的ESSID,并且对于逻辑链路控制层来说可以认为是一个BSS的话,那么这些BSS可以被统一为一个ESS。

在同一个ESS中的不同BSS之间切换的过程称为漫游。一般而言,一个ESS中的BSS都会使用相同的SSID和安全机制以提供接近于无缝漫游的可能。两个BSS之间通常有15%左右的重叠范围来保证漫游时信号不会长时间丢失,并且设置在不同频段来防止相互干扰。

WechatIMG362.jpeg

 
6、MAC

MAC地址采用十六进制数表示,共六个字节(48位)。(XX:XX:XX:XX:XX:XX )其中,前三个字节是由IEEE的注册管理机构RA负责给不同厂家分配的代码(高位24位),也称为“编制上唯一的标识符”(Organizationally Unique Identifier),后三个字节(低位24位)由各厂家自行指派给生产的适配器接口,称为扩展标识符(唯一性)。

三、历程

当产品部提出wifi考勤打卡需求时,普遍认为一个路由器有一个mac地址,手机连接wifi可以根据mac地址等信息进行打卡。当我们用多个手机连接公司名称为A(SSID)的wifi时,发现手机上展示的mac地址并不是一致的,这个就尴尬了,打翻了原有理念。
然后发现我们公司共有五个无线路由器,wifi名称都是A。哦,这时候才感觉到原来以前的知识还是靠谱的,可能是多个手机具体连接的路由器不是同一个。

然后把五个路由器wifi热点名称改为A、B、C、D、E,多个手机连接A热点时,发现手机得到的mac地址是一致的,到这里可以得出的结论是手机连接同一个wifi热点得到的mac地址是一致的。但是…..又尴尬了。

当多款手机连接B热点时,发现又出现了不一致的mac地址,查找原因发现,原来B无线路由器中可以设置2.4G Hz和5G Hz两个不同频段的wifi热点。B路由器中默认是开启2.4G Hz和5G Hz频段的wifi热点,并且wifi名称(SSID)是同一个。经过检查还有个问题是B路由器的出厂mac地址和手机连接得到的mac地址不一致。

例如上面举得例子:笔者公司的某款无线路由器B的出厂MAC地址为 XX:XX:XX:XX:XX:F1,当手机连接此wifi查看mac地址时发现是XX:XX:XX:XX:XX:F2,另一款手机连接时是XX:XX:XX:XX:XX:F3。由此可得出的结论是,路由器有一个基准(出厂)mac地址,然后发射出wifi的mac在基准mac地址上按照一定的算法进行变动,具体的变动算法不清楚,有清楚的请告知我,非常感谢。

另外还有一个问题是,C路由器设备后面所写的出厂说明mac地址是XX:XX:XX:XX:XX:56,但是通过路由器后台看到的出厂mac地址是XX:XX:XX:XX:XX:57,手机连接后得到的mac地址是XX:XX:XX:XX:XX:56。这就尴尬了,是厂家写错了还是根据特定的算法算的?

除了根据wifi设备分析外,我们也对具有wifi考勤打卡功能的软件进行了分析。比如现在比较火爆的由阿里团队研发的钉钉,以及纷享销客APP,在Android端,他们的处理都是获取周围wifi信息(并不是当前手机连接的wifi)进行打卡。在iOS端,他们的处理都是根据当前手机连接的wifi信息进行打卡。据iOS同事说,iOS获取周围wifi信息需要申请此功能,并最低支持版本是iOS 9。另外据可靠消息,分享逍客对mac地址的处理也是通过忽略低4位进行匹配。

四、结论

经过上述分析,手机获取的无线路由器MAC地址的低4位是变化的。那我们实现这个需求时,除了匹配虚拟位置、手机信息、wifi相关等其他信息外,只针对mac地址,我们可以忽略mac地址的低4位来做匹配。

五、参考资料

http://www.juniper.net/documentation/en_US/junos-space-apps12.3/network-director/topics/concept/wireless-ssid-bssid-essid.html 


qrcode_for_gh_08bfa7313fb2_258.jpg

微信公众号:IT大前端
关注可了解更多的大前端领域技术
1
评论

2019年3月3日凌晨阿里云宕机引发事故公告

beyond 发表了文章 • 4088 次浏览 • 2019-03-04 15:43 • 来自相关话题

环信的小伙伴,您好,

        首先,环信对2019年3月3日凌晨的事故为您造成的影响深表歉意,故障公告如下:

事故概述:

       3月2日晚23:55,阿里云华北2地域ECS出现了大面积宕机,导致使用这些服务的环信即时通讯云北京集群和VIP6集群服务不可用。
 




(阿里云事故公告)

环信客服云的用户,如果添加了受影响的IM集群上的APP Key作为APP渠道接入的关联并且使用环信IM SDK,也会出现收发消息失败的现象。

使用系统默认的APP渠道接入关联,支持第二通道的客户互动云访客端SDK和网页端的环信客户互动云用户均不受影响。

处理过程:
环信运维团队监控到异常后,第一时间联系了阿里云,在阿里云ECS服务全面恢复之前,利用少量可用的实例提前进行了服务恢复3月3日凌晨3:10,环信即时通讯云的北京集群和VIP6集群服务全部恢复

后续改进:
我们会同阿里云一起排查事故原因,防止此类事故再次发生,对您造成的影响深表歉意,感谢您对环信的支持。 查看全部
环信的小伙伴,您好,

        首先,环信对2019年3月3日凌晨的事故为您造成的影响深表歉意,故障公告如下:

事故概述:

       3月2日晚23:55,阿里云华北2地域ECS出现了大面积宕机,导致使用这些服务的环信即时通讯云北京集群和VIP6集群服务不可用。
 

微信图片_20190304154115.jpg

(阿里云事故公告)



环信客服云的用户,如果添加了受影响的IM集群上的APP Key作为APP渠道接入的关联并且使用环信IM SDK,也会出现收发消息失败的现象。

使用系统默认的APP渠道接入关联,支持第二通道的客户互动云访客端SDK和网页端的环信客户互动云用户均不受影响。

处理过程:
  • 环信运维团队监控到异常后,第一时间联系了阿里云,在阿里云ECS服务全面恢复之前,利用少量可用的实例提前进行了服务恢复
  • 3月3日凌晨3:10,环信即时通讯云的北京集群和VIP6集群服务全部恢复


后续改进:
  • 我们会同阿里云一起排查事故原因,防止此类事故再次发生,对您造成的影响深表歉意,感谢您对环信的支持。

0
回复

cocoapods 导入问题 Cocoapods 导入SDK 报错 导入 iOS

回复

Kion♚ 发起了问题 • 1 人关注 • 534 次浏览 • 2019-02-28 10:34 • 来自相关话题

1
回复

webim如何重置用户的密码,有没有类似注册的方法(conn.registerUser)直接调用? 环信_WebIM 环信_RestAPI

beyond 回复了问题 • 2 人关注 • 631 次浏览 • 2019-02-27 15:54 • 来自相关话题

1
回复

官方微信小程序出问题真机可以但是IDE进不了聊天室报错 有专职工程师值守

zd_SDK 回复了问题 • 2 人关注 • 532 次浏览 • 2019-02-27 14:23 • 来自相关话题

2
回复

swift自定义消息视图有人做过吗 环信_iOS

beyond 回复了问题 • 3 人关注 • 1449 次浏览 • 2019-02-27 14:06 • 来自相关话题

4
最佳

swift使用Pod集成EaseUI后打开聊天界面报错 环信_iOS

beyond 回复了问题 • 4 人关注 • 1218 次浏览 • 2019-02-27 14:05 • 来自相关话题

2
回复

2018-05-11发布的iOS SDK v2.x V2.3.4 Demo 在Xcode10上编译失败,libstdc++6.0.9.tbd等库没了,期待新版! 环信_iOS 环信2.X

zhaoliang 回复了问题 • 3 人关注 • 1912 次浏览 • 2019-02-27 14:04 • 来自相关话题

2
最佳

为什么sdk依赖这么多 SDK

beyond 回复了问题 • 3 人关注 • 1042 次浏览 • 2019-02-27 14:04 • 来自相关话题

4
最佳

ios环信自定义气泡的外边距怎么调整 环信_iOS

beyond 回复了问题 • 3 人关注 • 1283 次浏览 • 2019-02-27 14:04 • 来自相关话题

4
回复

悬赏金300元 求帮助 环信_iOS 环信_管理后台 环信移动客服 商务问题 环信_Android

beyond 回复了问题 • 5 人关注 • 3455 次浏览 • 2019-02-27 14:00 • 来自相关话题

2
回复

iOS EaseUI 只使用UI页面,不使用发生、接收消息,怎么处理 环信_iOS

beyond 回复了问题 • 3 人关注 • 981 次浏览 • 2019-02-27 13:58 • 来自相关话题

2
回复

java怎么集成环信注册用户 java 后台集成

beyond 回复了问题 • 2 人关注 • 1056 次浏览 • 2019-02-27 13:57 • 来自相关话题

3
最佳

请教站长的“打赏”功能如何实现的? 打赏

beyond 回复了问题 • 3 人关注 • 950 次浏览 • 2019-02-27 13:57 • 来自相关话题