V8 Profile

下面的命令可以生成一个v8的日志如 isolate-0x102d4e000-86008-v8.log –log-source-code 不是必传的字段,加了该字段可以在定位到源码 node --prof --log-source-code index.js 下一步是将log文件转成json node --prof-process --preprocess isolate-0x102d4e000-86008-v8.log > v8.json 然后打开 https://wangduanduan.gitee.io/v8-profiling/ 这个页面,选择v8.json 下图横坐标是时间,纵坐标是cpu百分比。 选择Bottom Up之后,展开JS unoptimized, 可以发现占用cpu比较高的代码的位置。

2022-10-29 11:37:55 · 1 min · Eddie Wang

前端必会的nginx知识点

1. 启动?停止?reload配置 nginx -s reload # 热重启 nginx -s reopen # 重启Nginx nginx -s stop # 快速关闭 nginx -s quit # 等待工作进程处理完成后关闭 nginx -T # 查看配置文件的实际内容 2. nginx如何做反向http代理 location ^~ /api { proxy_pass http://192.168.40.174:32020; } 3. nginx要如何配置才能处理跨域问题 location ^~ /p/asm { proxy_pass http://192.168.40.174:32020; add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,PATCH,OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Content-Type,ssid'; if ($request_method = 'OPTIONS') {return 204;} proxy_redirect off; proxy_set_header Host $host; } 4. 如何拦截某个请求,直接返回某个状态码? location ^~ /p/asm { return 204 "OK"; } 5....

2022-10-29 11:36:19 · 2 min · Eddie Wang

WebSocket断开码测试

WebSocket断开码,一般是用到的是从1000-1015。 正常的断开码是1000。其他的都是异常断开。 场景 服务端断开码 备注 刷新浏览器页面 1001 终端离开, 可能因为服务端错误, 也可能因为浏览器正从打开连接的页面跳转离开. 关闭浏览器tab页面 1001 终端离开, 可能因为服务端错误, 也可能因为浏览器正从打开连接的页面跳转离开. 关闭浏览器, 所有标签页都会关闭。 1001 可以发现。无论是刷新,关闭tab页面还是关闭浏览器,错误码都是1001 ws.close() 1005 主动调用close, 不传递错误码。对服务端来说,也是异常断开。1005表示没有收到预期的状态码. ws.close(1000) 1000 正常的关闭,客户端必需传递正确的错误原因码。原因码不是随便填入的。比如 ws.close(1009)aFailed to execute ‘close’ on ‘WebSocket’: The code must be either 1000, or between 3000 and 4999. 1009 is neither. 客户端断网

2022-10-29 11:34:02 · 1 min · Eddie Wang

Node.js读取wav文件

相比于普通的文件,二进制的文件略显神秘。本次就为大家揭开二进制文件的面纱。 WAV文件的格式 下图是一个普通的wav文件的格式。其中除了最后的data部分,其他的每个格子都占用了固定大小的字节数。 知道字节数之后,就需要按照正确的字节序读区。字节序读反了,可能读出一堆乱码。 关于字节序,可以参考阮一峰老师写的理解字节序这篇文章。 step1: 读取文件 const fs = require('fs') const path = require('path') const file = fs.readFileSync(path.join(__dirname, './a.wav')) console.log(file) 原始的打印,二进制以16进制的方式显示。看不出其中有何含义。 node main.js <Buffer 52 49 46 46 a4 23 48 00 57 41 56 45 66 6d 74 20 10 00 00 00 01 00 02 00 40 1f 00 00 00 7d 00 00 04 00 10 00 64 61 74 61 80 23 48 00 00 00 00 00 00 00 ....

2022-10-29 11:32:32 · 3 min · Eddie Wang

记一次WebRTC无回铃音问题排查

什么是回铃音? 回铃音的特点 回铃音是由运营商送给手机的,而不是由被叫送给主叫的。 回铃音的播放阶段是在被叫接听前播放,被叫一旦接听,回铃音则播放结束 回铃音一般是450Hz, 嘟一秒,停4秒,5秒一个周期 回铃音分为三种 舒适噪音阶段:就是嘟一秒,停4秒的阶段 彩铃阶段:有的手机,在接听之前,会向主叫方播放个性化的语音,例如放点流行音乐之类的 定制回音阶段:例如被叫放立即把电话给拒绝了,但是主叫放这边并没有挂电话,而是在播放:对不起,您拨打的电话无人接听,请稍后再播 问题现象 WebRTC拨打出去之后,在客户接听之前,听不到任何回铃音。在客户接听之后,可以短暂的听到一点点回铃音。 问题排查思路 服务端问题 客户端问题 网络问题 网络架构 首先根据网络架构图,我决定在a点和b点进行抓包 抓包之后用wireshark进行分析。得出以下结论 sip服务器AB之间用的是g711编码,语音流没有加密。从b点抓的包,能够从中提取出SIP服务器B向sip服务器A发送的语音流,可以听到回铃音。说明SIP服务器A是收到了回铃音的。 ab两点之间的WebRTC语音流是加密的,无法分析出其中是否含有语音流。 虽然无法提取出WebRTC语音流。但是通过wireshark Statistics -> Conversation 分析,得出结论:在电话接通之前,a点收到的udp包和从b点发出的udp包的数量是是一致的。说明webrtc客户端实际上是收到了语音流。只不过客户端没有播放。然后问题定位到客户端的js库。 通过分析客户端库的代码,定位到具体代码的位置。解决问题,并向开源库提交了修复bug的的pull request。实际上只是修改了一行代码。https://github.com/versatica/JsSIP/pull/669 问题总结 解决问题看似很简单,但是需要的很强的问题分析能力,并且对网络协议,网络架构,wireshark抓包分析都要精通,才能真正的看到深层次的东西。

2022-10-29 11:31:05 · 1 min · Eddie Wang

WebRTC getUserMedia DOMException Requested Device not found

在PC端,使用WebRTC通话一般都会使用耳麦,如果耳麦有问题,可能就会报这个错。 所以最好多换几个耳麦,试试。

2022-10-29 11:29:00 · 1 min · Eddie Wang

stompjs 使用x-queue-name指定队列名

client.onConnect = function (frame) { console.log('onConnect', frame) client.subscribe('/topic/event.agent.*.abc_cc', function (msg) { console.log(msg) }, { id: 'wdd', 'x-queue-name': 'wdd-queue' }) } 在mq管理端: Optional Arguments Optional queue arguments, also known as “x-arguments” because of their field name in the AMQP 0-9-1 protocol, is a map (dictionary) of arbitrary key/value pairs that can be provided by clients when a queue is declared. -https://www.rabbitmq.com/queues.html

2022-10-29 11:26:30 · 1 min · Eddie Wang

parseInt(0.0000005)为什么等于5?

最近看了一篇文章,里面提出一个问题? parseInt(0.0000005)为什么等于5? 最终也给出了解释,parseInt的第一个参数,如果不是字符串的话, 将会调用ToString方法,将其转为字符串。 string The value to parse. If this argument is not a string, then it is converted to one using theToStringabstract operation. Leadingwhitespacein this argument is ignored. MDN 我们在console面板上直接输入0.0000005回车之后发现是5e-7。我们使用toSting()方法转换之后发现是字符串5e7 字符串5e-7转成整数5是没什么疑问的,问题在于为什么0.0000005转成5e-7。而如果少一个零,就可以看到console会原样输出。 数值类型如何转字符串? 对于数值类型,是使用Number.toString()方法转换的。 Number.toString(x)的算法分析 这个算法并没有像我们想象的那么简单。 先说一些简单场景 简单场景 Number.toString(x) 如果x是NaN, 返回"NaN" 如果x是+0或者-0, 返回"0" 如果x是负数返回, 返回Number.toString(-x) 如果x是正无穷,返回"Infinity" 复杂场景 可以看出,0.0000005并不在简单场景中。下面就进入到复杂场景了。 会用到一个公式 k,s,n都是整数 k大于等于1 10的k-1次方小于等于s, 且s小于等于10的k次方 10的n-k次方属于实数 0.0000005可以表示为5*10的-7次方。代入上面的公式,可以算出: k=1, s=5, n=-6。 参考 https://dmitripavlutin.com/parseint-mystery-javascript/ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt https://tc39.es/ecma262/#sec-numeric-types-number-tostring

2022-10-29 11:22:57 · 1 min · Eddie Wang

{} Object.create({}) Object.create{null}的区别?

let a = {} let b = Object.create({}) let c = Object.create(null) console.log(a,b,c) 上面三个对象的区别是什么?

2022-10-29 11:20:09 · 1 min · Eddie Wang

Js Trailing Commas

简介 看下面的代码,如果我们要新增加一行"ccc", 实际我们的目的是增加一行,但是对于像git这种版本控制系统来说,我们改动了两行。 第三行进行了修改 第四行增加了 我们为什么要改动两行呢?因为如果不在第三行上的末尾加上逗号就增加第四行,则会报错语法错误。 var names = [ "aaa", "bbb" ] var names = [ "aaa", "bbb", "ccc" ] 尾逗号的提案就是允许再一些场景下,允许再尾部增加逗号。 var name = [ "aaa", "bbb", ] 那么我们再新增加一行的情况下,则只需要增加一行,而不需要修改之前行的代码。 var name = [ "aaa", "bbb", "ccc", ] 兼容性 除了IE浏览器没有对尾逗号全面支持以外,其他浏览器以及Node环境都已经全满支持 JSON是不支持尾逗号的,尾逗号只能在代码里面用 注意在包含尾逗号时数组长度的计算 [,,,].length // 3 [,,,1].length // 4 [,,,1,].length // 4 [1,,,].lenght // 3 使用场景 数组中使用 var abc = [ 1, 2, 3, ] 对象字面量中使用 var info = { name: "li", age: 12, } 作为形参使用 function say ( name, age, ) { } 作为实参使用 say( "li", 12, ) 在import中使用 import { A, B, C, } from 'D' 参考 https://developer....

2021-07-10 14:03:00 · 1 min · Eddie Wang