wvp-pro的事件监听模式和观察者模式

有关wvp-pro,不了解的可以网上查找资料,如新手使用wvp-pro和ZLMediaKit的菜鸟说明(手把手教)是个开源的项目,处理流媒体和实现国标28181信令。这里只谈源码的关键部分、设计模式和思想。其项目主要设计模式是事件监听和观察者模式,在异步非阻塞编程中,这两种模式是最常用有效的。事件监听和观察者模式就是为了实现程序的异步运行。实现程序异步运行的方法有很多,例如利用消息中间件,主流的消息中间件有kafka、rocketmq,mqtt等等。

redis中也有类似消息中间件的功能,消息中间件,无非就是实现消息的发布者和订阅者,redisTemplate.convertAndSend()主题消息生产者,消费者需要实现MessageListener接口,然后用下面方法初始化配置消费者订阅的主题消息(springboot已有集成)。
RedisMessageListenerContainer.addMessageListener(MessageListener接口实现类, new PatternTopic(“your topic”));
详细的例子,可查找相关资料,这里不做过多的描述,这里是为了说明,生产者消费者模式无处不在。回到wvp-pro,信令交互就是用到生产者消费者模式,观察者模式。部分关键源码如下图。

在这里插入图片描述

javax.sip.SipListener (是第三方包):
其实底下是 java.util.EventListener
在这里插入图片描述
在这里插入图片描述
SIPProcessorObserver 的观察者模式:

在这里插入图片描述
在这里插入图片描述
事件监听模式例子:

/**
 * 模拟业务数据
 **/
public class DataBean {
    public DataBean(String id,String info){
        this.id=id;
        this.info=info;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    private String id;
    private String info;
}
import java.util.EventObject;

/**
 * 事件类,用于封装事件源及一些与事件相关的参数.
 * 可以封装更多要处理的参数,DataBean模拟业务数据
 */
public class MyEvent extends EventObject {
    public DataBean getMeg() {
        return meg;
    }

    public void setMeg(DataBean meg) {
        this.meg = meg;
    }

    private DataBean meg;

    public MyEvent(Object source ,DataBean meg) {
        super(source);
        this.meg = meg;
    }
}
import java.util.ArrayList;
import java.util.List;

/**
 * 事件发布者,事件来源,也就是消息生产者,生成Event,并通知监听程序处理。Event里面携带业务数据。
 **/
public class EventPublisher {
    private final List<MyEventListener> listeners;
    public EventPublisher(){
        listeners = new ArrayList<>();
    }
    // 给事件源注册监听器
    public void addListener(MyEventListener listener) {
        this.listeners.add(listener);
    }
    // 当事件发生时,通知注册在该事件源上的所有监听器做出相应的反应(调用回调方法)
    public void publishAndnotifies(String id,String info) {
        MyEvent event= new MyEvent(this,new DataBean(id,info));
        for (MyEventListener listener : this.listeners) {
            listener.handleEvent(event);
        }
    }
}
import java.util.EventListener;

/**
 * 事件监听者,当事件发生时,处理事件里的消息。
 **/
public interface MyEventListener extends EventListener {
    void handleEvent(MyEvent event);
}
public class MyEventMain {
    public static void main(String args[]){
        EventPublisher publisher = new EventPublisher();

        // 注册监听器
        publisher.addListener(new MyEventListener() {
            @Override
            public void handleEvent(MyEvent e) {
                System.out.println(e.getSource().toString());
                System.out.println(e.getMeg().getId()+"::"+e.getMeg().getInfo());
            }
        });

        //发布事件
        publisher.publishAndnotifies("id1","message1");
        publisher.publishAndnotifies("id2","message2");

    }
}

附:wvp-pro几处优化的地方 ( 版本2.7.1 ):

com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.InviteRequestProcessor
 public SIPResponse sendStreamAck(SIPRequest request, SendRtpItem sendRtpItem, ParentPlatform platform)
 
/*content.append("m=video " + localPort + " RTP/AVP 96\r\n");
        content.append("a=sendonly\r\n");
        content.append("a=rtpmap:96 PS/90000\r\n");
        if (sendRtpItem.isTcp()) {
            content.append("a=connection:new\r\n");
            if (!sendRtpItem.isTcpActive()) {
                content.append("a=setup:active\r\n");
            } else {
                content.append("a=setup:passive\r\n");
            }
        }*/

        if (sendRtpItem.isTcp()) {
            content.append("m=video " + localPort + " TCP/RTP/AVP 96\r\n");
            content.append("a=sendonly\r\n");
            content.append("a=rtpmap:96 PS/90000\r\n");
            content.append("a=connection:new\r\n");
            if (!sendRtpItem.isTcpActive()) {
                content.append("a=setup:active\r\n");
            } else {
                content.append("a=setup:passive\r\n");
            }
        } else {
            content.append("m=video " + localPort + " RTP/AVP 96\r\n");
            content.append("a=sendonly\r\n");
            content.append("a=rtpmap:96 PS/90000\r\n");
        }
        // 替换上面注释

com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.NotifyRequestForCatalogProcessor
在这里插入图片描述

在这里插入图片描述

com.genersoft.iot.vmp.storager.impl.VideoManagerStorageImpl
public boolean resetChannels(String deviceId, List deviceChannelList) {}
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最好Tony

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值