关于freeswitch听不到客户端声音的那些事
在初次使用freeswitch的过程中,经常会碰到听不见对方声音的问题。产生这种问题的根本原因还是因为NAT穿越的问题。如果freeswitch和客户端在一个网络上是不会出现这个问题的,主要还是因为freeswitch和客户端一个在内网中,一个在公网中。客户端和freeswitch通信是通过路由器的NAT穿越完成。比如说freeswitch是部署在公网的一台服务器上,而客户端是安装在用户的内网的一台电脑上,这台电脑通过路由器访问互联网。所以这里就存在路由器把内网客户端的地址转换为公网地址的一个过程。1、客户端和freeswitch之间通信的方式在说明这个问题之前我还是先来看看客户端和freeswitch是怎么通信的。这里的客户端指的是可以进行语音或者视频的客户端,它和freeswitch是通过SIP协议通信的,但是中间的语音流或者视频流又是通过SDP协议传输双方地址和编码格式等其他进行媒体协商的必要信息的,真正的语音流或者视频流是通过RTP传输的。那么听不到声音的问题应该是和SDP协议有关,所以我们来详细看一下SDP协议是什么:SDP协议简介v=0 o=FreeSWITCH 15981
2020-08-23 技术分享
我们的劳动究竟创造了多少价值
我们劳动创造的价值怎么去衡量?这是最近我在思考的一个问题。因为工作久了就会思考工作的意义到底是什么,人毕竟是一种需要意义才能存活的生物嘛。在写这篇文章之前,我一直认为劳动创造的价值是不是就是直接或者间接和大自然交换所产生的价值,比如开采石油的企业就创造了价值,农民种植农作物也是创造了价值,但是等我写完这篇文章,我发现这只是表面现象,真正的本质还不是这些。要讨论劳动创造的价值,那么我们得从人类的历史来看。在农耕时代,人们通过种植农作物,过着自给自足的农耕生活。这时候人们劳动只是为了填饱自己的肚子,而且最多只能吃饱,吃到好的可能还不是那么容易。或者说要吃到世界上的各种东西是不可能的,也就是说在这种时代,人们连满足自己的口腹之欲都很难做到。就算在集市中也是如此,因为受制于地域和运输速度的限制,也只能吃到一个地区自己产的食物,不像今天我们可以在一个城市吃遍世界各地的美食。到了工业时代,人们可能不需要都去种地了。有做汽车的车间工人,有做衣服的纺织工人,也有坐在办公室的管理人员。他们通过自己的体力或脑力劳动就可以换取工资,然后用钱去换取食物或者其他满足自己需要的东西。人们分工协作的作用开始显现出来
2020-08-16 人生哲学
如何删除Redis Hash数据结构中的子键呢?
Redis可以设置某个键的过期时间这个我们都知道,可是你知道怎么过期删除Hash键中某个子键吗?Redis中可没有直接提供这样设置Hash键的子键的过期方法,但是我们可以自己用Redis实现这个需求。这里我们需要借用Redis中另外一个数据结构,那就是ZSET。我们在往Hash键中增加一个子键的时候,同时把该子键将要过期的时间戳当做score放进一个ZSET数据结构的键中,在用一个定时任务去定时扫描ZSET键,获取键中小于当前时间的子键,然后就可以根据这样获得的子键去Hash键中删除对应的子键了。这样说可能有点抽象,我们用一个具体的例子来说明一下。假如我们有一个这样的Hash键:CallRecord,然后里面存储的hkey是一个电话号码,value是这个电话号码的呼叫状态。然后有这样一个ZSET:CallRecord:ExpireAt,只要我们每产生一个呼叫记录,就把电话号码当做子键,对应电话号码相应的过期时间当做score塞进这个ZSET。这个过期时间可以是当前时间戳加上一个时间段,比如12小时。然后我们写一个定时任务,每分钟或者每秒(这个频率可以自己设置)扫描这个CallRecor
2020-07-22 技术分享
如何减少重复日志
在实际项目中,你可能会遇到被大量重复日志刷屏的苦恼,这种短时间内重复的日志不仅浪费服务器内存,而且影响你看其他日志。那么你可能会想,有没有一种方法能够让我既打印出这些日志,但又不想重复日志太多的方法。最近我就遇到了这种需求,有些日志不能不打,不然出了问题回过头来发现没有日志也不好定位问题,但是有时候因为定时任务的原因,这种日志又比较多,于是我就想着怎么去减少这种重复的日志。最朴素的想法就是给重复的日志计数,达到指定的数目就打一条日志,这样就达到了减少重复日志输出的目的。这样做的好处是不用借助其他框架,直接修改打印日志的代码就好了。坏处就是可能会对代码有一定的侵入性。于是顺着这个思路,我写了一个减少打印重复日志的工具类,在原来打印日志的地方调用这个工具类就可以起到减少重复日志的效果。代码如下:import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** * 用来减少打印重复日志
2020-07-22 技术分享
volatile为什么能禁止指令重排
在回答题目之前我们先来思考这样一个问题,就是指令重排是什么,我们为什么又要禁止它,以及在什么时候要禁止指令重排?我们都知道,像Java等高级语言最后都要被编译器转换为机器语言,或者称作机器指令,以便能被机器直接执行。所以,我们编写的程序最后都是一条条机器指令,从而能被CPU执行。在计算机组成原理这门课中,我们知道,这些指令被放在指令寄存器中,由程序计数器PC去指示CPU下一条该执行那条指令。CPU先从程序计数器中拿到下一条指令在指令寄存器的地址,计数器加一,然后把指令从指令寄存器中读出来,最后执行,然后又循环这个过程。又由于CPU的速度远大于寄存器的速度,所以为了增加CPU的并发度,在多核CPU中可能会有多核去拿指令,然后执行,所以在这个过程中,原本的代码顺序可能会被重新排序,这就是指令重排。当然,在单线程下,有些语句的顺序天然不能被重排,比如下面这种:int a = 1; // A int b = 2; // B int c = a * b; // C C的执行顺序必须在A和B后面,因为C依赖A和B,这种情况叫做as-if-serial语义。但是A和
2020-07-05 技术分享