存档5月 2020

less less-loader

npm install less less-loader --save-dev
yarn add less less-loader --dev
````

[官网](https://less.bootcss.com/ "官网")https://less.bootcss.com/

在 Node.js 环境中使用 Less :
npm install -g less
> lessc styles.less styles.css

在浏览器环境中使用 Less :

““

coTrun

https://github.com/coturn/coturn
https://github.com/bprodoehl/docker-turnserver
带有Coturn STUN和TURN server (https://github.com/coturn/coturn)的Docker容器,
ocker run -d -e EXTERNAL_IP=1.2.3.4 –name=turnserver –restart=”on-failure:10″ –net=host -p 3478:3478 -p 3478:3478/udp bprodoehl/turnserver
环境参数
SKIP_AUTO_IP-绑定到地址,当与–net =host一起运行时,对IPv4和IPv6双协议栈很有用,EXTERNAL_IP –可选手动指定的外部IP地址端口–监听端口用于STUN和TURNLISTEN_ON_PUBLIC_IP –绑定到外部IPUSE_IPV4 –在确定外部IP时强制IPv4

下载安装

一、ubuntu安装软件包
# apt install coturn

二、配置coturnls
1、复制DTLS、TLS支持的证书文件:
# cp/usr/share/coturn/examples/etc/turn_server_cert.pem /etc/turn_server_cert.pem
# cp/usr/share/coturn/examples/etc/turn_server_pkey.pem /etc/turn_server_pkey.pem
2、编辑/etc/turnserver.conf文件:
listening-port=3478
tls-listening-port=5349
listening-ip=192.168.1.230
external-ip=47.104.19.243(NAT必须)
lt-cred-mech
user=tcp:123456(必须)
realm=example.com(必须)
3、编辑/etc/default/coturn文件:
TURNSERVER_ENABLED=1(必须)

三、完成安装
1、重启coturn
# service coturn restart

2、测试验证
# turnadmin -a -u test -r leifeng-elec.com-p test
# turnutils_uclient 192.168.1.230 -u test -wtest

可以先安装环境
sudo apt-get install libssl-dev
sudo apt-get install libevent-dev
sudo apt-get install libpq-dev
sudo apt-get install mysql-client
sudo apt-get install libmysqlclient-dev
sudo apt-get install libhiredis-dev
sudo apt-get install git

git clone https://github.com/coturn/coturn
./configure --prefix=/usr/local/coturn
make && make install

1) If your system supports automatic start-up system daemon services, 
then to enable the turnserver as a system service that is automatically
started, you have to:

    a) Create and edit /etc/turnserver.conf or 
    /usr/local/etc/turnserver.conf . 
    Use /usr/local/etc/turnserver.conf.default as an example.

    b) For user accounts settings: set up SQLite or PostgreSQL or 
    MySQL or MongoDB or Redis database for user accounts.
    Use /usr/local/share/turnserver/schema.sql as SQL database schema,
    or use /usr/local/share/turnserver/schema.userdb.redis as Redis
    database schema description and/or 
    /usr/local/share/turnserver/schema.stats.redis
    as Redis status & statistics database schema description.

    If you are using SQLite, the default database location is in 
    /var/db/turndb or in /usr/local/var/db/turndb or in /var/lib/turn/turndb.

    c) add whatever is necessary to enable start-up daemon for the 
    /usr/local/bin/turnserver.

2) If you do not want the turnserver to be a system service, 
   then you can start/stop it "manually", using the "turnserver" 
   executable with appropriate options (see the documentation).

3) To create database schema, use schema in file 
/usr/local/share/turnserver/schema.sql.

4) For additional information, run:

   $ man turnserver
   $ man turnadmin
   $ man turnutils

ERROR: OpenSSL Crypto development libraries are not installed properly in required location.
apt-get install libssl-dev

生成md5码:turnadmin -k –u 用户名 -r nanjing -p 密码

生成证书
sudo openssl req -x509 -newkey rsa:2048 -keyout /etc/turn_server_pkey.pem -out /etc/turn_server_cert.pem -days 99999 -nodes

创建turnuserdb.conf文件
vi /etc/turnuserdb.conf
在其中填入之前生成的用户名和key

配制参数 编辑文件/etc/turnserver.conf
listening-port=3478
external-ip=公网IP
user=username:password
realm=域名
以上常用,以下按需
listening-device=填写自己的网卡类型
relay-device=填写自己的网卡类型
listening-ip=ip地址
listening-port=3478
tls-listening-port=5349
listening-ip与relay-ip采用内网ip,external-ip是外网的ip
relay-ip=ip地址
external-ip=ip地址
relay-threads=50
lt-cred-mech
static-auth-secret=用户名
user=用户名:密钥
userdb=/etc/turnuserdb.conf
#max-bps=102400
pidfile="/var/run/turnserver.pid"
no-loopback-peers
no-multicast-peers
sha256
mobility
no-cli
cert=/etc/turn_server_cert.pem
pkey=/etc/turn_server_pkey.pem
stale-nonce
use-auth-secret
Verbose
fingerprint

运行:
sudo turnserver -L 23.83.233.168 -o -a -b /etc/turnuserdb.conf -f -r nanjing

修改信令连接
 var pcConfig = {
            'iceServers': [
                {
                    'url': 'stun:xx.xx.xx.xxip:3478',
                },
                {
                    'url': 'stun:stun.xx.xx.xx.xxip:3478',
                },
                {
                'urls': 'turn:xxx.cn:3478',
                'credential': "mypasswd", or 密钥
                'username': "myname"
            }]
        };

可以根据需要调整其他参数。有关更多信息,请查看Coturn帮助页面:
https://github.com/coturn/coturn/wiki/turnserver
https://github.com/coturn/coturn/wiki/CoturnConfig
编辑文件/etc/default/coturn并取消注释TURNSERVER_ENABLED=1,以便TURN服务器自动启动为系统服务守护程序。

在防火墙中打开以下端口:
3478 TCP和UDP。
49152 – 65535 UDP:按照 RFC 5766,这些是TURN服务器用于交换媒体的端口。可以使用TURN服务器上的min-port和max-port参数更改这些端口。
注意
虽然RFC指定了TURN使用的端口,但如果使用STUN,则需要打开所有UDP端口,因为STUN不会限制可能使用的端口范围。

测试地址
https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

Wireshark

mac下用Wireshark抓包报错you don’t have permission to capture on that device

cd /dev
ls -la | grep bp

看到用户组所属
crw——- 1 root wheel 23, 0 6 23 23:42 bpf0
crw——- 1 root wheel 23, 1 6 23 23:42 bpf1
crw——- 1 root wheel 23, 2 6 23 23:43 bpf2
crw——- 1 root wheel 23, 3 6 23 23:42 bpf3

这样导致上述没有权限问题,需要手动修改,确保所有列表有你的用户名和admin作为用户组。
whoami 命令看你当前用户名
sudo chown 上面看到的用户名:admin bp*

test:
https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice

socket.io for java

Server

<dependency>
      <groupId>com.corundumstudio.socketio</groupId>
      <artifactId>netty-socketio</artifactId>
      <version>1.7.16</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.7.2</version>
    </dependency>

public class ServerStart {

    public static void main(String [] args){
        Configuration config = new Configuration();
        config.setHostname("localhost");
        config.setPort(9999);
        SocketIOServer server = new SocketIOServer(config);
        server.addConnectListener(new ConnectListener() {
            // 添加客户端连接监听器
            public void onConnect(SocketIOClient client) {
                //logger.info(client.getRemoteAddress() + " web客户端接入");
                //不知道如何与客户端对应,好的办法是自己去写对应的函数
                client.sendEvent("connected", "hello");
            }
        });

        //监听客户端事件,client_info为事件名称,-自定义事件
         server.addEventListener("client_info", String.class, new DataListener<String>(){
            public void onData(SocketIOClient client, String data, AckRequest ackRequest) throws ClassNotFoundException {
                //客户端推送advert_info事件时,onData接受数据,这里是string类型的json数据,还可以为Byte[],object其他类型
                String sa = client.getRemoteAddress().toString();
                String clientIp = sa.substring(1,sa.indexOf(":"));//获取客户端连接的ip
                Map params = client.getHandshakeData().getUrlParams();//获取客户端url参数
                System.out.println(clientIp+":客户端:************"+data);
            }
         });

        //添加客户端断开连接事件
        server.addDisconnectListener(new DisconnectListener(){
            public void onDisconnect(SocketIOClient client) {
                String sa = client.getRemoteAddress().toString();
                String clientIp = sa.substring(1,sa.indexOf(":"));//获取设备ip
                System.out.println(clientIp+"-------------------------"+"客户端已断开连接");
                //给客户端发送消息
                client.sendEvent("advert_info",clientIp+"客户端你好,我是服务端,期待下次和你见面");
            }
        });
        server.start();

        while (true){
            try {
                Thread.sleep(1500);
                //广播消息
                server.getBroadcastOperations().sendEvent("borcast","are you live?");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Client

        <dependency>
            <groupId>io.socket</groupId>
            <artifactId>socket.io-client</artifactId>
            <version>1.0.0</version>
        </dependency>

public class AppStart {

    public static void main(String [] args){
        String url ="http://localhost:9999";
        try{
            IO.Options options = new IO.Options();
            options.transports = new String[]{"websocket"};
            options.reconnectionAttempts = 2;
            options.reconnectionDelay = 1000;//失败重连的时间间隔
            options.timeout = 500;//连接超时时间(ms)
            //par1 是任意参数
            final Socket socket = IO.socket(url+"?par1=1234", options);

            socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {

                public void call(Object... args) {
                    socket.send("hello");
                }
            });

            //自定义事件
            socket.on("borcast", new Emitter.Listener() {
                public void call(Object... objects) {
                    System.out.println("receive borcast data:" + objects[0].toString());
                }
            });

            socket.on("connected", new Emitter.Listener() {
                public void call(Object... objects) {
                    System.out.println("receive connected data:" + objects[0].toString());
                }
            });

            socket.connect();
            //循环发送数据
            while (true){
                socket.emit("client_info"," 客户端在发送数据");
                Thread.sleep(2000);
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}

VUE
https://www.npmjs.com/package/vue-socket.io

import VueSocketIO from 'vue-socket.io'
import SocketIO from 'socket.io-client'

Vue.use(new VueSocketIO({
  debug: true,
  connection: SocketIO('http://192.168.88.108:443', {
    path: '', // path千万不要写“/”
    transports: ['websocket', 'xhr-polling', 'jsonp-polling']
  }) // options object is Optional
}))

Other https://github.com/probil/vue-socket.io-extended

import Vue from 'vue'
import VueSocketIOExt from 'vue-socket.io-extended'
import SocketIO from 'socket.io-client';

const socket = SocketIO('https://localhost');
export default ({ store }) => {
  Vue.use(VueSocketIOExt, socket, { store });
}

sockets: {
      // 创建连接
      connect() {
        console.log('连接成功啦')
      },
      // 监听断开连接,函数
      disconnect() {
        console.log('断开服务器连接');
        this.connectdisabled = false;
        this.leavedisabled = true;
        this.senddisabled = true;
        this.inputdisabled = true;
      },
      reconnect() {
        console.log("重新链接");
      },
      // 监听自定义事件,需与服务端emit事件名一致
      joined(room, id) {
        console.log('joined',room, id)
        this.connectdisabled = true;
        this.leavedisabled = false;
        this.senddisabled = false;
        this.inputdisabled = false;
      },

//发送加入信令
this.$socket.client.emit('join', this.room)

ESLint

ESLint
规则的细节请到ESLint官方网站查看 http://eslint.org/docs/rules/

配置esLint
eslint配置方式主要有两种:

注释配置:使用js注释来直接嵌入ESlint配置信息到一个文件里
配置文件:使用一个js,JSON或者YAML文件来给整个目录和它的子目录指定配置信息。这些配置可以写成一个文件名.eslintrc.*的文件或者package.json文件里的eslintConfig项里
这两种方式ESlint都会自动寻找然后读取,也可以直接在命令行内指定一个配置文件。
一般需要我们去配置项包括:

环境:你的脚本会在哪种环境下运行。每个环境带来了一组特定的预定义的全局变量。
全局变量:脚本运行期间会访问额外的全局变量。
规则:使用那些规则,并且规则的等级是多少。
vue-cli脚手架安装完成后,主要有几个地方配置了eslint。

1,项目创建后项目中就会出现.eslintignore 和.eslintrc.js两个文件
.eslintignore类似Git的.gitignore用来配置不需要Eslint检查的文件
.eslintrc.js主要用来配置具体规则

.eslintignore文件

添加不启动静态检查的文件

build/*.js // 忽略build文件夹下所有的脚本文件
config/*.js
.eslintrc.js文件

// https://eslint.org/docs/user-guide/configuring
module.exports = {
  root: true,
  parser: 'babel-eslint', // 解析器为babel-eslint,可在package.json文件中配置
  parserOptions: {
    sourceType: 'module'
  },
  env: { //环境配置为浏览器
    browser: true,
  },
  // https://github.com/standard/standard/blob/master/docs/RULES-en.md
  extends: 'standard', //文件配置继承standard规则,具体访问连接
  // required to lint *.vue files
  plugins: [
    'html'
  ],
  // add your custom rules here
  'rules': { // 添加自定义规则
    // allow paren-less arrow functions
    'arrow-parens': 0,
    // allow async-await
    'generator-star-spacing': 0,
    // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
  }
}
说明: 在rules中每个配置项后面的第一个值为eslint规则的错误等级

"off" 或 0 (关闭这条规则)
"warn" 或 1 (违反规则会警告,不影响项目运行)
"error" 或 2 (违反规则会报错,终止项目运行)
2 在package.json文件中配置文件

"script" : {
    "lint": "eslint --ext .js, .vue src"
}
"devDenpendencies" : {
    "babel-eslint": "^7.1.1",
    // 更多eslint文件
    ...
}
#### 3 在webpack配置文件中 ####

webpack.base.conf.js

  module: {
    rules: [
      {
        test: /\.(js|vue)$/,
        loader: 'eslint-loader',
        enforce: 'pre',
        include: [resolve('src'), resolve('test')],
        options: {
          formatter: require('eslint-friendly-formatter')
        }
      }
    ]
  }
有时候代码里有些特殊情况需要我们在某一行或者某几行关闭ESLint检测,可以使用注释:

1,注释关闭所有规则

/* eslint-disable */
alert('foo');
/* eslint-enable */
2,关闭某一行的所有规则

alert('foo'); // eslint-disable-line
// eslint-disable-next-line
alert('foo');
3,在某一行关闭指定的规则

alert('foo'); // eslint-disable-line no-alert
// eslint-disable-next-line no-alert
alert('foo');

babel-loader

https://www.webpackjs.com/loaders/babel-loader/
““
webpack 3.x | babel-loader 8.x | babel 7.x
npm install babel-loader@8.0.0-beta.0 @babel/core @babel/preset-env webpack

webpack 3.x babel-loader 7.x | babel 6.x
npm install babel-loader babel-core babel-preset-env webpack

编译工具
npm i babel-cli // 这是babel解释器的客户端主程序
npm i babel-core // babel的核心文件,好像默认会自动安装
npm i babel-preset-es2015 // 把代码转换成ES6
npm i babel-preset-stage-0 // 把代码转换成ES7

在package.json中修改运行脚本
–exec babel-node
在根路径创建.babelrc文件,写入配置
.babelrc
{
“presets”: [“es2015″,”stage-0”]
}