fix(amap):core
This commit is contained in:
parent
622bc2ea8b
commit
bb81cda972
18
src/App.tsx
18
src/App.tsx
|
@ -1,10 +1,10 @@
|
||||||
import { Outlet } from "react-router";
|
import { Outlet } from "react-router";
|
||||||
import MapUtl from "./components/map/mapUtil";
|
import MapUtl from "./components/map/mapUtil";
|
||||||
import { useEffect } from "react";
|
import SocketService from "./util/socket";
|
||||||
// import SocketService from "./util/socket";
|
const socketService = SocketService.getInstance();
|
||||||
// const socketService = SocketService.getInstance();
|
|
||||||
const onMessage = (e: any) => {
|
const onMessage = (e: any) => {
|
||||||
let data = JSON.parse(e);
|
let data = JSON.parse(e);
|
||||||
|
console.log(data)
|
||||||
if (data.type === "accpt") {
|
if (data.type === "accpt") {
|
||||||
let body = JSON.parse(data.content.body);
|
let body = JSON.parse(data.content.body);
|
||||||
MapUtl.addMaker({
|
MapUtl.addMaker({
|
||||||
|
@ -23,9 +23,19 @@ const onMessage = (e: any) => {
|
||||||
});
|
});
|
||||||
maker?.setPosition([body.long, body.lat]);
|
maker?.setPosition([body.long, body.lat]);
|
||||||
}
|
}
|
||||||
|
else if (data.type === "move") {
|
||||||
|
let maker: any = null;
|
||||||
|
let body = JSON.parse(data.content.body);
|
||||||
|
MapUtl.makerList?.forEach((e) => {
|
||||||
|
if (e.userIdentity === body?.user_identity) {
|
||||||
|
maker = e.marker;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
maker?.setPosition([body.long, body.lat]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// socketService.on("message", onMessage);
|
socketService.on("message", onMessage);
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -48,7 +48,7 @@ const Ec = (props: Store) => {
|
||||||
{userList.map((item: any) => {
|
{userList.map((item: any) => {
|
||||||
return (
|
return (
|
||||||
<div key={item.account}>
|
<div key={item.account}>
|
||||||
<div>姓名:{item.account} : 未在线</div>
|
<div>姓名:{item.user_name} : 未在线</div>
|
||||||
<p></p>
|
<p></p>
|
||||||
<div>
|
<div>
|
||||||
点击呼叫:
|
点击呼叫:
|
||||||
|
|
|
@ -23,7 +23,6 @@ export const columns: ColumnsType<UserDataType> = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export const defaultConfig = [
|
export const defaultConfig = [
|
||||||
|
|
||||||
{
|
{
|
||||||
type: FormType.input,
|
type: FormType.input,
|
||||||
label: "法规标题",
|
label: "法规标题",
|
||||||
|
@ -31,21 +30,26 @@ export const defaultConfig = [
|
||||||
value: "",
|
value: "",
|
||||||
rules: [{ required: true, message: "请输入法规标题!" }],
|
rules: [{ required: true, message: "请输入法规标题!" }],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: FormType.inputNumber,
|
||||||
|
label: "等级排序",
|
||||||
|
name: "level",
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: FormType.input,
|
type: FormType.input,
|
||||||
label: "法规副标题",
|
label: "法规副标题",
|
||||||
name: "sub_title",
|
name: "sub_title",
|
||||||
value: "",
|
value: "",
|
||||||
rules: [{ required: true, message: "请输入法规副标题!" }],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "editor",
|
type: FormType.editor,
|
||||||
label: "内容",
|
label: "内容",
|
||||||
name: "content",
|
name: "content",
|
||||||
value: "",
|
value: "",
|
||||||
rules: [{ required: true, message: "请填写内容" }],
|
rules: [{ required: true, message: "请填写内容" }],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: "upload",
|
type: "upload",
|
||||||
label: "附件图片",
|
label: "附件图片",
|
||||||
|
|
|
@ -7,17 +7,7 @@ import SimpleForm from "@/components/form/simple_form";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { columns, defaultCatConfig } from "./dict_column";
|
import { columns, defaultCatConfig } from "./dict_column";
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
const list = [
|
|
||||||
{ id: 1, name: "婚姻" },
|
|
||||||
{ id: 2, name: "政治面貌" },
|
|
||||||
{ id: 3, name: "文化程度" },
|
|
||||||
{ id: 4, name: "民族" },
|
|
||||||
{ id: 5, name: "单位性质" },
|
|
||||||
{ id: 6, name: "服役军兵种" },
|
|
||||||
{ id: 7, name: "军衔" },
|
|
||||||
{ id: 8, name: "技术职称" },
|
|
||||||
{ id: 9, name: "职务级别" },
|
|
||||||
];
|
|
||||||
const Dict = (props: Store) => {
|
const Dict = (props: Store) => {
|
||||||
const { sysStore } = props;
|
const { sysStore } = props;
|
||||||
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
||||||
|
@ -130,7 +120,7 @@ const Dict = (props: Store) => {
|
||||||
<>
|
<>
|
||||||
<Form.Item key="drop_type" label="类型" name="drop_type" rules={[]}>
|
<Form.Item key="drop_type" label="类型" name="drop_type" rules={[]}>
|
||||||
<Select placeholder="">
|
<Select placeholder="">
|
||||||
{list?.map((v: any) => {
|
{sysStore.list?.map((v: any) => {
|
||||||
return (
|
return (
|
||||||
<Option key={v.id} value={v.id}>
|
<Option key={v.id} value={v.id}>
|
||||||
{v.name}
|
{v.name}
|
||||||
|
|
|
@ -2,8 +2,7 @@ import { FormType } from "@/components/form/interface";
|
||||||
import { UserDataType } from "@/model/userModel";
|
import { UserDataType } from "@/model/userModel";
|
||||||
import { ColumnsType } from "antd/lib/table";
|
import { ColumnsType } from "antd/lib/table";
|
||||||
import { Image } from "antd";
|
import { Image } from "antd";
|
||||||
export const defaultConfig =(team,per)=>
|
export const defaultConfig = (team, per) => [
|
||||||
[
|
|
||||||
{
|
{
|
||||||
type: FormType.input,
|
type: FormType.input,
|
||||||
label: "用户名",
|
label: "用户名",
|
||||||
|
@ -16,14 +15,8 @@ export const defaultConfig =(team,per)=>
|
||||||
label: "性别",
|
label: "性别",
|
||||||
name: "sex",
|
name: "sex",
|
||||||
radioData: [
|
radioData: [
|
||||||
{
|
{ key: "男", val: 1 },
|
||||||
key: "男",
|
{ key: "女", val: 2 },
|
||||||
val: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "女",
|
|
||||||
val: 2,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
value: 0,
|
value: 0,
|
||||||
rules: [{ required: true, message: "请选择性别" }],
|
rules: [{ required: true, message: "请选择性别" }],
|
||||||
|
@ -49,7 +42,7 @@ export const defaultConfig =(team,per)=>
|
||||||
value: "",
|
value: "",
|
||||||
rules: [{ required: true, message: "请输入登录账号" }],
|
rules: [{ required: true, message: "请输入登录账号" }],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: FormType.input,
|
type: FormType.input,
|
||||||
label: "家庭住址",
|
label: "家庭住址",
|
||||||
|
@ -57,7 +50,7 @@ export const defaultConfig =(team,per)=>
|
||||||
value: "",
|
value: "",
|
||||||
rules: [{ required: true, message: "请输入家庭住址" }],
|
rules: [{ required: true, message: "请输入家庭住址" }],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: FormType.input,
|
type: FormType.input,
|
||||||
label: "担任职务",
|
label: "担任职务",
|
||||||
|
@ -72,7 +65,7 @@ export const defaultConfig =(team,per)=>
|
||||||
value: "",
|
value: "",
|
||||||
rules: [{ required: true, message: "请输入通讯地址" }],
|
rules: [{ required: true, message: "请输入通讯地址" }],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: FormType.input,
|
type: FormType.input,
|
||||||
label: "贯籍",
|
label: "贯籍",
|
||||||
|
@ -80,7 +73,7 @@ export const defaultConfig =(team,per)=>
|
||||||
value: "",
|
value: "",
|
||||||
rules: [{ required: true, message: "请输入贯籍" }],
|
rules: [{ required: true, message: "请输入贯籍" }],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: FormType.input,
|
type: FormType.input,
|
||||||
label: "联系电话",
|
label: "联系电话",
|
||||||
|
@ -99,7 +92,7 @@ export const defaultConfig =(team,per)=>
|
||||||
type: FormType.cehckboxGroup,
|
type: FormType.cehckboxGroup,
|
||||||
label: "所属队伍",
|
label: "所属队伍",
|
||||||
name: "team_link_user",
|
name: "team_link_user",
|
||||||
checkboxData:team,
|
checkboxData: team,
|
||||||
value: "",
|
value: "",
|
||||||
rules: [{ required: true, message: "请选择所属队伍" }],
|
rules: [{ required: true, message: "请选择所属队伍" }],
|
||||||
},
|
},
|
||||||
|
@ -107,7 +100,7 @@ export const defaultConfig =(team,per)=>
|
||||||
type: FormType.cehckboxGroup,
|
type: FormType.cehckboxGroup,
|
||||||
label: "个人身份属性",
|
label: "个人身份属性",
|
||||||
name: "pers_link_user",
|
name: "pers_link_user",
|
||||||
checkboxData:per,
|
checkboxData: per,
|
||||||
value: "",
|
value: "",
|
||||||
rules: [{ required: true, message: "请选择个人身份属性" }],
|
rules: [{ required: true, message: "请选择个人身份属性" }],
|
||||||
},
|
},
|
||||||
|
@ -145,7 +138,6 @@ export const defaultConfig =(team,per)=>
|
||||||
],
|
],
|
||||||
rules: [{ required: true, message: "单位类型不能为空" }],
|
rules: [{ required: true, message: "单位类型不能为空" }],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: FormType.radio,
|
type: FormType.radio,
|
||||||
label: "民兵类型",
|
label: "民兵类型",
|
||||||
|
@ -198,7 +190,7 @@ export const defaultConfig =(team,per)=>
|
||||||
name: "serv_unit",
|
name: "serv_unit",
|
||||||
value: "",
|
value: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: FormType.input,
|
type: FormType.input,
|
||||||
label: "专业特长",
|
label: "专业特长",
|
||||||
|
@ -212,72 +204,6 @@ export const defaultConfig =(team,per)=>
|
||||||
name: "email",
|
name: "email",
|
||||||
value: "",
|
value: "",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
type: FormType.radio,
|
|
||||||
label: "积极力量",
|
|
||||||
name: "a_member",
|
|
||||||
value: 1,
|
|
||||||
radioData: [
|
|
||||||
{
|
|
||||||
key: "是",
|
|
||||||
val: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "否",
|
|
||||||
val: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: FormType.radio,
|
|
||||||
label: "专业队伍",
|
|
||||||
name: "p_team",
|
|
||||||
value: 1,
|
|
||||||
radioData: [
|
|
||||||
{
|
|
||||||
key: "是",
|
|
||||||
val: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "否",
|
|
||||||
val: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
type: FormType.radio,
|
|
||||||
label: "是否为社干力量",
|
|
||||||
name: "c_member",
|
|
||||||
value: 2,
|
|
||||||
radioData: [
|
|
||||||
{
|
|
||||||
key: "是",
|
|
||||||
val: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "否",
|
|
||||||
val: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: FormType.radio,
|
|
||||||
label: "三方力量",
|
|
||||||
name: "o_member",
|
|
||||||
value: 2,
|
|
||||||
radioData: [
|
|
||||||
{
|
|
||||||
key: "是",
|
|
||||||
val: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "否",
|
|
||||||
val: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
type: FormType.textarea,
|
type: FormType.textarea,
|
||||||
label: "描述",
|
label: "描述",
|
||||||
|
|
|
@ -19,7 +19,7 @@ class SysStore extends BaseStore<TagDataType> {
|
||||||
bannerList: observable,
|
bannerList: observable,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async addBanner(param: any) {
|
async addBanner(param: any) {
|
||||||
await baseHttp.post(SysConfig.ADDBanner, param)
|
await baseHttp.post(SysConfig.ADDBanner, param)
|
||||||
this.getbanner();
|
this.getbanner();
|
||||||
|
@ -28,7 +28,18 @@ class SysStore extends BaseStore<TagDataType> {
|
||||||
let res = await baseHttp.get(SysConfig.LISTBannler, {})
|
let res = await baseHttp.get(SysConfig.LISTBannler, {})
|
||||||
this.bannerList = res.data.record
|
this.bannerList = res.data.record
|
||||||
}
|
}
|
||||||
bannerList:Array<any> = []
|
bannerList: Array<any> = []
|
||||||
|
list: Array<any> = [
|
||||||
|
{ id: 1, name: "婚姻" },
|
||||||
|
{ id: 2, name: "政治面貌" },
|
||||||
|
{ id: 3, name: "文化程度" },
|
||||||
|
{ id: 4, name: "民族" },
|
||||||
|
{ id: 5, name: "单位性质" },
|
||||||
|
{ id: 6, name: "服役军兵种" },
|
||||||
|
{ id: 7, name: "军衔" },
|
||||||
|
{ id: 8, name: "技术职称" },
|
||||||
|
{ id: 9, name: "职务级别" },
|
||||||
|
];
|
||||||
}
|
}
|
||||||
export const sysStore = new SysStore()
|
export const sysStore = new SysStore()
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
class Config {
|
class Config {
|
||||||
// static baseUrl = "https://rw.quwanya.cn/";
|
static baseUrl = "https://rw.quwanya.cn/";
|
||||||
static uploadUrl = "https://rw.quwanya.cn/";
|
static uploadUrl = "https://rw.quwanya.cn/";
|
||||||
// static ws = "wss://rw.quwanya.cn/wsadmin?id=admin";
|
static ws = "ws://rw.quwanya.cn:12214/wsadmin?id=admin";
|
||||||
static rtc = "wss://rw.quwanya.cn/ws";
|
static rtc = "wss://rw.quwanya.cn/ws";
|
||||||
static ws = "ws://127.0.0.1:12214/ws?id=admin";
|
// static ws = "ws://127.0.0.1:12214/ws?id=admin";
|
||||||
static baseUrl = "http://127.0.0.1:12214/";
|
// static baseUrl = "http://127.0.0.1:12214/";
|
||||||
// static uploadUrl = "http://127.0.0.1:12214/";
|
// static uploadUrl = "http://127.0.0.1:12214/";
|
||||||
|
|
||||||
}
|
}
|
||||||
export default Config;
|
export default Config;
|
||||||
|
|
||||||
|
|
|
@ -1,145 +1,144 @@
|
||||||
import Config from "./config"
|
import Config from "./config"
|
||||||
|
|
||||||
export type AutoReconnectOptions = boolean | {
|
export type AutoReconnectOptions = boolean | {
|
||||||
maxRetries?: number
|
maxRetries?: number
|
||||||
retryInterval?: number
|
retryInterval?: number
|
||||||
onMaxRetriesReached?: Function
|
onMaxRetriesReached?: Function
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ConnectionStatus {
|
||||||
|
Disconnected = 'DISCONNECTED',
|
||||||
|
Connected = 'CONNECTED',
|
||||||
|
Error = 'ERROR'
|
||||||
|
}
|
||||||
|
|
||||||
|
class SocketService {
|
||||||
|
private static instance: SocketService | null = null
|
||||||
|
private adminws: WebSocket | null = null
|
||||||
|
private listeners: Record<string, Function[]> = {}
|
||||||
|
private autoReconnect: AutoReconnectOptions = true
|
||||||
|
private times: any = null
|
||||||
|
private retries: number = 0
|
||||||
|
private connectionStatus: ConnectionStatus = ConnectionStatus.Disconnected
|
||||||
|
|
||||||
|
private constructor() {
|
||||||
|
this.connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ConnectionStatus {
|
public static getInstance(): SocketService {
|
||||||
Disconnected = 'DISCONNECTED',
|
if (!SocketService.instance) {
|
||||||
Connected = 'CONNECTED',
|
SocketService.instance = new SocketService()
|
||||||
Error = 'ERROR'
|
}
|
||||||
|
return SocketService.instance
|
||||||
}
|
}
|
||||||
|
|
||||||
class SocketService {
|
public setAutoReconnectOptions(options: AutoReconnectOptions) {
|
||||||
private static instance: SocketService | null = null
|
this.autoReconnect = options
|
||||||
private adminws: WebSocket | null = null
|
}
|
||||||
private listeners: Record<string, Function[]> = {}
|
|
||||||
private autoReconnect: AutoReconnectOptions = true
|
public connect() {
|
||||||
private times: any = null
|
this.adminws = new WebSocket(Config.ws)
|
||||||
private retries: number = 0
|
this.adminws.onopen = () => {
|
||||||
private connectionStatus: ConnectionStatus = ConnectionStatus.Disconnected
|
this.connectionStatus = ConnectionStatus.Connected
|
||||||
|
this.emit('connected', null)
|
||||||
private constructor() {
|
this.hert()
|
||||||
this.connect()
|
|
||||||
}
|
}
|
||||||
|
this.adminws.onerror = () => {
|
||||||
public static getInstance(): SocketService {
|
this.connectionStatus = ConnectionStatus.Error
|
||||||
if (!SocketService.instance) {
|
clearTimeout(this.times)
|
||||||
SocketService.instance = new SocketService()
|
this.emit('error', null)
|
||||||
}
|
|
||||||
return SocketService.instance
|
|
||||||
}
|
}
|
||||||
|
this.adminws.onclose = () => {
|
||||||
public setAutoReconnectOptions(options: AutoReconnectOptions) {
|
this.connectionStatus = ConnectionStatus.Disconnected
|
||||||
this.autoReconnect = options
|
clearTimeout(this.times)
|
||||||
|
this.emit('disconnected', null)
|
||||||
|
if (this.shouldReconnect()) {
|
||||||
|
setTimeout(() => this.connect(), this.getRetryInterval())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.adminws.onmessage = (event) => {
|
||||||
public connect() {
|
this.emit('message', event.data)
|
||||||
this.adminws = new WebSocket(Config.ws)
|
}
|
||||||
this.adminws.onopen = () => {
|
}
|
||||||
this.connectionStatus = ConnectionStatus.Connected
|
public hert() {
|
||||||
this.emit('connected', null)
|
this.times = setInterval(() => this.send({ type: "heartbeat", data: {} }), 3000)
|
||||||
this.hert()
|
}
|
||||||
}
|
private shouldReconnect(): boolean {
|
||||||
this.adminws.onerror = () => {
|
if (typeof this.autoReconnect === 'boolean') {
|
||||||
this.connectionStatus = ConnectionStatus.Error
|
return this.autoReconnect
|
||||||
clearTimeout(this.times)
|
} else if (this.autoReconnect) {
|
||||||
this.emit('error', null)
|
const { maxRetries } = this.autoReconnect
|
||||||
}
|
|
||||||
this.adminws.onclose = () => {
|
if (maxRetries !== undefined) {
|
||||||
this.connectionStatus = ConnectionStatus.Disconnected
|
if (this.retries < maxRetries) {
|
||||||
clearTimeout(this.times)
|
this.retries++
|
||||||
this.emit('disconnected', null)
|
return true
|
||||||
if (this.shouldReconnect()) {
|
} else if (this.retries >= maxRetries) {
|
||||||
setTimeout(() => this.connect(), this.getRetryInterval())
|
this.autoReconnect.onMaxRetriesReached && this.autoReconnect.onMaxRetriesReached()
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.adminws.onmessage = (event) => {
|
|
||||||
this.emit('message', event.data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public hert(){
|
return false
|
||||||
this.times = setInterval(() => this.send({"type":"heartbeat"}), 3000)
|
}
|
||||||
}
|
|
||||||
private shouldReconnect(): boolean {
|
private getRetryInterval(): number {
|
||||||
if (typeof this.autoReconnect === 'boolean') {
|
if (typeof this.autoReconnect === 'boolean') {
|
||||||
return this.autoReconnect
|
|
||||||
} else if (this.autoReconnect) {
|
|
||||||
const { maxRetries } = this.autoReconnect
|
|
||||||
|
|
||||||
if (maxRetries !== undefined) {
|
|
||||||
if (this.retries < maxRetries) {
|
|
||||||
this.retries++
|
|
||||||
return true
|
|
||||||
} else if (this.retries >= maxRetries) {
|
|
||||||
this.autoReconnect.onMaxRetriesReached && this.autoReconnect.onMaxRetriesReached()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private getRetryInterval(): number {
|
|
||||||
if (typeof this.autoReconnect === 'boolean') {
|
|
||||||
return 1000
|
|
||||||
} else if (this.autoReconnect && this.autoReconnect.retryInterval) {
|
|
||||||
return this.autoReconnect.retryInterval
|
|
||||||
}
|
|
||||||
return 1000
|
return 1000
|
||||||
|
} else if (this.autoReconnect && this.autoReconnect.retryInterval) {
|
||||||
|
return this.autoReconnect.retryInterval
|
||||||
}
|
}
|
||||||
|
return 1000
|
||||||
public send(data: any) {
|
}
|
||||||
if (this.adminws && this.adminws.readyState === WebSocket.OPEN) {
|
|
||||||
this.adminws.send(JSON.stringify(data))
|
public send(data: any) {
|
||||||
} else {
|
if (this.adminws && this.adminws.readyState === WebSocket.OPEN) {
|
||||||
console.error('WebSocket 连接未打开')
|
this.adminws.send(JSON.stringify(data))
|
||||||
}
|
} else {
|
||||||
}
|
console.error('WebSocket 连接未打开')
|
||||||
|
|
||||||
public close() {
|
|
||||||
if (this.adminws) {
|
|
||||||
this.adminws.close()
|
|
||||||
SocketService.instance = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private emit(event: string, data: any) {
|
|
||||||
if (!this.listeners[event]) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.listeners[event].forEach((listener) => listener(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
public on(event: string, listener: Function) {
|
|
||||||
if (!this.listeners[event]) {
|
|
||||||
this.listeners[event] = []
|
|
||||||
}
|
|
||||||
this.listeners[event].push(listener)
|
|
||||||
if (event === 'connected' && this.connectionStatus === ConnectionStatus.Connected) {
|
|
||||||
listener()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public off(event: string, listener: Function) {
|
|
||||||
if (!this.listeners[event]) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.listeners[event] = this.listeners[event].filter((l) => l !== listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
public getConnectionStatus(): ConnectionStatus {
|
|
||||||
return this.connectionStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
public watchConnectionStatus(callback: (status: ConnectionStatus) => void) {
|
|
||||||
this.on('connected', () => callback(ConnectionStatus.Connected))
|
|
||||||
this.on('disconnected', () => callback(ConnectionStatus.Disconnected))
|
|
||||||
this.on('error', () => callback(ConnectionStatus.Error))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SocketService
|
public close() {
|
||||||
|
if (this.adminws) {
|
||||||
|
this.adminws.close()
|
||||||
|
SocketService.instance = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private emit(event: string, data: any) {
|
||||||
|
if (!this.listeners[event]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.listeners[event].forEach((listener) => listener(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
public on(event: string, listener: Function) {
|
||||||
|
if (!this.listeners[event]) {
|
||||||
|
this.listeners[event] = []
|
||||||
|
}
|
||||||
|
this.listeners[event].push(listener)
|
||||||
|
if (event === 'connected' && this.connectionStatus === ConnectionStatus.Connected) {
|
||||||
|
listener()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public off(event: string, listener: Function) {
|
||||||
|
if (!this.listeners[event]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.listeners[event] = this.listeners[event].filter((l) => l !== listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
public getConnectionStatus(): ConnectionStatus {
|
||||||
|
return this.connectionStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
public watchConnectionStatus(callback: (status: ConnectionStatus) => void) {
|
||||||
|
this.on('connected', () => callback(ConnectionStatus.Connected))
|
||||||
|
this.on('disconnected', () => callback(ConnectionStatus.Disconnected))
|
||||||
|
this.on('error', () => callback(ConnectionStatus.Error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SocketService
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
import Config from "./config";
|
import Config from "./config";
|
||||||
|
import SocketService from "./socket";
|
||||||
|
|
||||||
class WebRtc {
|
class WebRtc {
|
||||||
private mediaStream: MediaStream | Blob | null = null;
|
private mediaStream: MediaStream | Blob | null = null;
|
||||||
|
@ -17,57 +18,52 @@ class WebRtc {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
async init() {
|
async init() {
|
||||||
this.ws = new WebSocket(Config.rtc)
|
|
||||||
this.ws.addEventListener('open', this.open);
|
|
||||||
let that = this;
|
|
||||||
this.createOffer()
|
this.createOffer()
|
||||||
this.ws.onmessage = function (evt) {
|
// this.ws.onmessage = function (evt) {
|
||||||
let msg = JSON.parse(evt.data)
|
// let msg = JSON.parse(evt.data)
|
||||||
if (!msg) {
|
// if (!msg) {
|
||||||
return console.log('failed to parse msg')
|
// return console.log('failed to parse msg')
|
||||||
}
|
// }
|
||||||
switch (msg.type) {
|
// switch (msg.type) {
|
||||||
case 'offer':
|
// case 'offer':
|
||||||
let offer = msg.data.description
|
// let offer = msg.data.description
|
||||||
that.pee?.setRemoteDescription(offer)
|
// that.pee?.setRemoteDescription(offer)
|
||||||
that.pee?.createAnswer().then(answer => {
|
// that.pee?.createAnswer().then(answer => {
|
||||||
that.pee?.setLocalDescription(answer)
|
// that.pee?.setLocalDescription(answer)
|
||||||
that.ws?.send(JSON.stringify({
|
// that.ws?.send(JSON.stringify({
|
||||||
type: 'answer', data: {
|
// type: 'answer', data: {
|
||||||
'to': msg.data.from,
|
// 'to': msg.data.from,
|
||||||
'from': "31283192",
|
// 'from': "31283192",
|
||||||
'description': { 'sdp': answer.sdp, 'type': answer.type },
|
// 'description': { 'sdp': answer.sdp, 'type': answer.type },
|
||||||
'session_id': msg.data.from + "-31283192",
|
// 'session_id': msg.data.from + "-31283192",
|
||||||
}
|
// }
|
||||||
}))
|
// }))
|
||||||
})
|
// })
|
||||||
return
|
// return
|
||||||
|
|
||||||
case 'candidate':
|
// case 'candidate':
|
||||||
let candidate = msg.data.candidate
|
// let candidate = msg.data.candidate
|
||||||
if (!candidate) {
|
// if (!candidate) {
|
||||||
return console.log('failed to parse candidate')
|
// return console.log('failed to parse candidate')
|
||||||
}
|
// }
|
||||||
that.pee?.addIceCandidate(candidate)
|
// that.pee?.addIceCandidate(candidate)
|
||||||
break;
|
// break;
|
||||||
case "answer":
|
// case "answer":
|
||||||
that.pee?.setRemoteDescription(msg.data.description)
|
// that.pee?.setRemoteDescription(msg.data.description)
|
||||||
break;
|
// break;
|
||||||
case "bye":
|
// case "bye":
|
||||||
that.pee?.close()
|
// that.pee?.close()
|
||||||
that.close()
|
// that.close()
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
async createOffer() {
|
async createOffer() {
|
||||||
|
|
||||||
var url =
|
var url =
|
||||||
'http://rw.quwanya.cn:12217/api/turn?service=turn&username=flutter-webrtc';
|
'https://rw.quwanya.cn/api/turn?service=turn&username=flutter-webrtc';
|
||||||
fetch(url)
|
fetch(url)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
|
||||||
const configuration = {
|
const configuration = {
|
||||||
iceServers: [
|
iceServers: [
|
||||||
{
|
{
|
||||||
|
@ -79,15 +75,18 @@ class WebRtc {
|
||||||
}
|
}
|
||||||
this.gets(configuration)
|
this.gets(configuration)
|
||||||
})
|
})
|
||||||
try {
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 设置远程offer
|
||||||
|
setRemoteDes(answer) {
|
||||||
|
this.pee?.setRemoteDescription(answer)
|
||||||
|
}
|
||||||
|
addCandidate(candidate) {
|
||||||
|
if (!candidate) {
|
||||||
|
return console.log('failed to parse candidate')
|
||||||
|
}
|
||||||
|
this.pee?.addIceCandidate(candidate)
|
||||||
|
}
|
||||||
async gets(configuration) {
|
async gets(configuration) {
|
||||||
console.log(configuration);
|
|
||||||
const peerConnection = new RTCPeerConnection(configuration);
|
const peerConnection = new RTCPeerConnection(configuration);
|
||||||
this.pee = peerConnection
|
this.pee = peerConnection
|
||||||
// 获取远方流添加到页面播放
|
// 获取远方流添加到页面播放
|
||||||
|
@ -97,7 +96,7 @@ class WebRtc {
|
||||||
remoteVideo.controls = true
|
remoteVideo.controls = true
|
||||||
remoteVideo.srcObject = event.streams[0];
|
remoteVideo.srcObject = event.streams[0];
|
||||||
console.log(event);
|
console.log(event);
|
||||||
|
|
||||||
event.track.onmute = function () {
|
event.track.onmute = function () {
|
||||||
remoteVideo.play()
|
remoteVideo.play()
|
||||||
}
|
}
|
||||||
|
@ -123,10 +122,10 @@ class WebRtc {
|
||||||
that.ws?.send(JSON.stringify({
|
that.ws?.send(JSON.stringify({
|
||||||
type: "offer", "data": {
|
type: "offer", "data": {
|
||||||
"to": userId,
|
"to": userId,
|
||||||
"from": "31283192",
|
"from": "admin",
|
||||||
"description": offer,
|
"description": offer,
|
||||||
"media": "video",
|
"media": "video",
|
||||||
"session_id": userId + "-31283192",
|
"session_id": userId + "-admin",
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
|
@ -150,20 +149,33 @@ class WebRtc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
calls(userId) {
|
calls(userId) {
|
||||||
this.sendOffer(userId)
|
this.sendOffer("admin123")
|
||||||
if (this.video) {
|
if (this.video) {
|
||||||
this.video.srcObject = this.mediaStream;
|
this.video.srcObject = this.mediaStream;
|
||||||
this.video.autoplay = true;
|
this.video.autoplay = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 发送本地offer
|
||||||
|
setIceOffer(offer, toid) {
|
||||||
|
this.pee?.setRemoteDescription(offer)
|
||||||
|
this.pee?.createAnswer().then(answer => {
|
||||||
|
this.pee?.setLocalDescription(answer)
|
||||||
|
SocketService.getInstance().send({
|
||||||
|
type: 'answer', data: {
|
||||||
|
'to': toid,
|
||||||
|
'from': "admin",
|
||||||
|
'description': { 'sdp': answer.sdp, 'type': answer.type },
|
||||||
|
'session_id': toid + "-admin",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
close() {
|
close() {
|
||||||
this.video?.pause();
|
this.video?.pause();
|
||||||
this.pee?.close();
|
this.pee?.close();
|
||||||
this.ws?.send(JSON.stringify({
|
this.ws?.send(JSON.stringify({
|
||||||
"type": "bye", "data": {
|
"type": "bye", "data": {
|
||||||
"session_id": this.userToId + "31283192",
|
"session_id": this.userToId + "admin",
|
||||||
"to": this.userToId
|
"to": this.userToId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue