From e5123a74eb16b070270ad99bf9d81597d437c191 Mon Sep 17 00:00:00 2001 From: joestarzxh Date: Thu, 23 Apr 2026 11:24:05 +0800 Subject: [PATCH] =?UTF-8?q?[fix]router=E5=8D=95=E5=85=83=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E6=8B=86=E5=88=86=EF=BC=8C=E6=AF=94=E8=BE=83=E6=96=B9=E4=BE=BF?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/logs/lalserver.log | 210 --------------------------- server/router.go | 297 +------------------------------------- server/router_ctrl.go | 143 ++++++++++++++++++ server/router_fmp4.go | 31 ++++ server/router_helper.go | 29 ++++ server/router_rtc.go | 57 ++++++++ server/router_stat.go | 65 +++++++++ 7 files changed, 330 insertions(+), 502 deletions(-) delete mode 100644 server/logs/lalserver.log create mode 100644 server/router_ctrl.go create mode 100644 server/router_fmp4.go create mode 100644 server/router_helper.go create mode 100644 server/router_rtc.go create mode 100644 server/router_stat.go diff --git a/server/logs/lalserver.log b/server/logs/lalserver.log deleted file mode 100644 index e0043cb..0000000 --- a/server/logs/lalserver.log +++ /dev/null @@ -1,210 +0,0 @@ -2026/04/23 10:34:35.896771  INFO initial log succ. - config.go:249 -2026/04/23 10:34:35.896771  INFO  - __ ___ __ - / / / | / / - / / / /| | / / - / /___/ ___ |/ /___ -/_____/_/ |_/_____/ - - config.go:252 -2026/04/23 10:34:35.896771  WARN config version invalid. conf version of lalserver=v0.4.1, conf version of config file= - config.go:262 -2026/04/23 10:34:35.896771  WARN config some fields do not exist which have been set to the zero value. fields=[conf_version rtmp.addr rtmp.rtmps_enable rtmp.rtmps_addr rtmp.rtmps_cert_file rtmp.rtmps_key_file rtmp.gop_num rtmp.single_gop_max_frame_num rtmp.merge_write_size in_session.add_dummy_audio_enable in_session.add_dummy_audio_wait_audio_ms httpflv.enable httpflv.enable_https httpflv.url_pattern httpflv.gop_num httpflv.single_gop_max_frame_num hls.enable hls.enable_https hls.url_pattern hls.use_memory_as_disk_flag hls.out_path hls.fragment_duration_ms hls.fragment_num hls.delete_threshold hls.cleanup_mode hls.sub_session_timeout_ms hls.sub_session_hash_key httpts.enable httpts.enable_https httpts.url_pattern httpts.gop_num httpts.single_gop_max_frame_num rtsp.addr rtsp.rtsps_enable rtsp.rtsps_addr rtsp.rtsps_cert_file rtsp.rtsps_key_file rtsp.out_wait_key_frame_flag rtsp.ws_rtsp_enable rtsp.ws_rtsp_addr rtsp.auth_enable rtsp.auth_method rtsp.username rtsp.password record.enable_flv record.flv_out_path record.enable_mpegts record.mpegts_out_path relay_push.enable relay_push.addr_list static_relay_pull.enable static_relay_pull.addr http_api.addr server_id http_notify.enable http_notify.update_interval_sec http_notify.on_server_start http_notify.on_update http_notify.on_pub_start http_notify.on_pub_stop http_notify.on_sub_start http_notify.on_sub_stop http_notify.on_relay_pull_start http_notify.on_relay_pull_stop http_notify.on_rtmp_connect http_notify.on_hls_make_ts simple_auth.key simple_auth.dangerous_lal_secret simple_auth.pub_rtmp_enable simple_auth.sub_rtmp_enable simple_auth.sub_httpflv_enable simple_auth.sub_httpts_enable simple_auth.pub_rtsp_enable simple_auth.sub_rtsp_enable simple_auth.hls_m3u8_enable pprof.addr debug.log_group_interval_sec debug.log_group_max_group_num debug.log_group_max_sub_num_per_group] - config.go:278 -2026/04/23 10:34:35.900773  WARN config some log fields do not exist which have been set to default value. log.level=LevelDebug, log.filename=./logs/lalserver.log, log.is_to_stdout=true, log.is_rotate_daily=true, log.short_file_flag=true, log.timestamp_flag=true, log.timestamp_with_ms_flag=true, log.level_flag=true, log.assert_behavior=AssertError - config.go:283 -2026/04/23 10:34:35.900773  INFO load conf succ. raw content={"rtmp":{"enable":false},"rtsp":{"enable":false},"http_api":{"enable":false},"pprof":{"enable":false}} parsed=&{ConfVersion: RtmpConfig:{Enable:false Addr: RtmpsEnable:false RtmpsAddr: RtmpsCertFile: RtmpsKeyFile: GopNum:0 SingleGopMaxFrameNum:0 MergeWriteSize:0} InSessionConfig:{AddDummyAudioEnable:false AddDummyAudioWaitAudioMs:0} DefaultHttpConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:}} HttpflvConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} HlsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} UseMemoryAsDiskFlag:false MuxerConfig:{OutPath: FragmentDurationMs:0 FragmentNum:0 DeleteThreshold:0 CleanupMode:0} SubSessionTimeoutMs:0 SubSessionHashKey:} HttptsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} RtspConfig:{Enable:false Addr: RtspsEnable:false RtspsAddr: RtspsCertFile: RtspsKeyFile: OutWaitKeyFrameFlag:false WsRtspEnable:false WsRtspAddr: ServerAuthConfig:{AuthEnable:false AuthMethod:0 UserName: PassWord:}} RecordConfig:{EnableFlv:false FlvOutPath: EnableMpegts:false MpegtsOutPath:} RelayPushConfig:{Enable:false AddrList:[]} StaticRelayPullConfig:{Enable:false Addr:} HttpApiConfig:{Enable:false Addr:} ServerId: HttpNotifyConfig:{Enable:false UpdateIntervalSec:0 OnServerStart: OnUpdate: OnPubStart: OnPubStop: OnSubStart: OnSubStop: OnRelayPullStart: OnRelayPullStop: OnRtmpConnect: OnHlsMakeTs:} SimpleAuthConfig:{Key: DangerousLalSecret: PubRtmpEnable:false SubRtmpEnable:false SubHttpflvEnable:false SubHttptsEnable:false PubRtspEnable:false SubRtspEnable:false HlsM3u8Enable:false} PprofConfig:{Enable:false Addr:} LogConfig:{Level:1 Filename:./logs/lalserver.log IsToStdout:true IsRotateDaily:true IsRotateHourly:false ShortFileFlag:true TimestampFlag:true TimestampWithMsFlag:true LevelFlag:true AssertBehavior:1 HookBackendOutFn:} DebugConfig:{LogGroupIntervalSec:0 LogGroupMaxGroupNum:0 LogGroupMaxSubNumPerGroup:0}} - config.go:346 -2026/04/23 10:34:35.900773  INFO  start: 2026-04-23 10:34:35.866 - base.go:35 -2026/04/23 10:34:35.900773  INFO  wd: F:\开源\go\lalmi\lalmax\server - base.go:36 -2026/04/23 10:34:35.900773  INFO  args: C:\Users\ADMINI~1\AppData\Local\Temp\go-build490025007\b363\server.test.exe -test.testlogfile=C:\Users\ADMINI~1\AppData\Local\Temp\go-build490025007\b363\testlog.txt -test.paniconexit0 -test.timeout=10m0s - base.go:37 -2026/04/23 10:34:35.900773  INFO  bininfo: GitTag=unknown. GitCommitLog=unknown. GitStatus=unknown. BuildTime=unknown. GoVersion=unknown. runtime=windows/amd64. - base.go:38 -2026/04/23 10:34:35.900773  INFO  version: lal v0.37.4 (github.com/q191201771/lal) - base.go:39 -2026/04/23 10:34:35.901773  INFO  github: https://github.com/q191201771/lal - base.go:40 -2026/04/23 10:34:35.901773  INFO  doc: https://pengrl.com/lal - base.go:41 -2026/04/23 10:34:35.901773  INFO lalmax http listen. addr=:52349 - server.go:103 -2026/04/23 10:34:35.901773  INFO [GROUP1] lifecycle new group. group=0xc000091888, appName=, streamName=test - group__.go:185 -2026/04/23 10:34:35.901773  INFO [CUSTOMIZEPUB1] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:34:35.901773 DEBUG [GROUP1] [CUSTOMIZEPUB1] add customize pub session into group. - group__in.go:33 -2026/04/23 10:34:35.901773  INFO create group, uniqueKey:, streamKey:test - group.go:108 -2026/04/23 10:34:35.902774  INFO SetGroup, streamKey:test - group_manager.go:105 -2026/04/23 10:34:35.902774  INFO AddSubscriber, streamKey:test, subscriberId:consumer1, protocol:LALMAX - group.go:237 -2026/04/23 10:34:35.902774 ERROR http notify post error. err=Post "http://127.0.0.1:55559/on_update": dial tcp 127.0.0.1:55559: connectex: No connection could be made because the target machine actively refused it., url=http://127.0.0.1:55559/on_update, info={EventCommonInfo:{ServerId:} Groups:[]} - http_notify.go:216 -2026/04/23 10:34:35.902774  INFO [GROUP2] lifecycle new group. group=0xc000091c08, appName=, streamName=notify_test - group__.go:185 -2026/04/23 10:34:35.902774  INFO [CUSTOMIZEPUB2] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:34:35.902774 DEBUG [GROUP2] [CUSTOMIZEPUB2] add customize pub session into group. - group__in.go:33 -2026/04/23 10:34:35.902774  INFO create group, uniqueKey:, streamKey:notify_test - group.go:108 -2026/04/23 10:34:35.902774  INFO SetGroup, streamKey:notify_test - group_manager.go:105 -2026/04/23 10:34:35.902774  INFO AddSubscriber, streamKey:notify_test, subscriberId:consumer_notify, protocol:LALMAX - group.go:237 -2026/04/23 10:34:38.903343  INFO http api start rtp pub. req info={StreamName:rtp_pub_test Port:0 TimeoutMs:0 IsTcpFlag:0 DebugDumpPacket:} - router.go:245 -2026/04/23 10:34:38.904493  INFO http api stop rtp pub. stream_name=rtp_pub_test, session_id= - router.go:271 -2026/04/23 10:37:23.154712  INFO initial log succ. - config.go:249 -2026/04/23 10:37:23.155229  INFO  - __ ___ __ - / / / | / / - / / / /| | / / - / /___/ ___ |/ /___ -/_____/_/ |_/_____/ - - config.go:252 -2026/04/23 10:37:23.155229  WARN config version invalid. conf version of lalserver=v0.4.1, conf version of config file= - config.go:262 -2026/04/23 10:37:23.155229  WARN config some fields do not exist which have been set to the zero value. fields=[conf_version rtmp.addr rtmp.rtmps_enable rtmp.rtmps_addr rtmp.rtmps_cert_file rtmp.rtmps_key_file rtmp.gop_num rtmp.single_gop_max_frame_num rtmp.merge_write_size in_session.add_dummy_audio_enable in_session.add_dummy_audio_wait_audio_ms httpflv.enable httpflv.enable_https httpflv.url_pattern httpflv.gop_num httpflv.single_gop_max_frame_num hls.enable hls.enable_https hls.url_pattern hls.use_memory_as_disk_flag hls.out_path hls.fragment_duration_ms hls.fragment_num hls.delete_threshold hls.cleanup_mode hls.sub_session_timeout_ms hls.sub_session_hash_key httpts.enable httpts.enable_https httpts.url_pattern httpts.gop_num httpts.single_gop_max_frame_num rtsp.addr rtsp.rtsps_enable rtsp.rtsps_addr rtsp.rtsps_cert_file rtsp.rtsps_key_file rtsp.out_wait_key_frame_flag rtsp.ws_rtsp_enable rtsp.ws_rtsp_addr rtsp.auth_enable rtsp.auth_method rtsp.username rtsp.password record.enable_flv record.flv_out_path record.enable_mpegts record.mpegts_out_path relay_push.enable relay_push.addr_list static_relay_pull.enable static_relay_pull.addr http_api.addr server_id http_notify.enable http_notify.update_interval_sec http_notify.on_server_start http_notify.on_update http_notify.on_pub_start http_notify.on_pub_stop http_notify.on_sub_start http_notify.on_sub_stop http_notify.on_relay_pull_start http_notify.on_relay_pull_stop http_notify.on_rtmp_connect http_notify.on_hls_make_ts simple_auth.key simple_auth.dangerous_lal_secret simple_auth.pub_rtmp_enable simple_auth.sub_rtmp_enable simple_auth.sub_httpflv_enable simple_auth.sub_httpts_enable simple_auth.pub_rtsp_enable simple_auth.sub_rtsp_enable simple_auth.hls_m3u8_enable pprof.addr debug.log_group_interval_sec debug.log_group_max_group_num debug.log_group_max_sub_num_per_group] - config.go:278 -2026/04/23 10:37:23.155229  WARN config some log fields do not exist which have been set to default value. log.level=LevelDebug, log.filename=./logs/lalserver.log, log.is_to_stdout=true, log.is_rotate_daily=true, log.short_file_flag=true, log.timestamp_flag=true, log.timestamp_with_ms_flag=true, log.level_flag=true, log.assert_behavior=AssertError - config.go:283 -2026/04/23 10:37:23.155229  INFO load conf succ. raw content={"rtmp":{"enable":false},"rtsp":{"enable":false},"http_api":{"enable":false},"pprof":{"enable":false}} parsed=&{ConfVersion: RtmpConfig:{Enable:false Addr: RtmpsEnable:false RtmpsAddr: RtmpsCertFile: RtmpsKeyFile: GopNum:0 SingleGopMaxFrameNum:0 MergeWriteSize:0} InSessionConfig:{AddDummyAudioEnable:false AddDummyAudioWaitAudioMs:0} DefaultHttpConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:}} HttpflvConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} HlsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} UseMemoryAsDiskFlag:false MuxerConfig:{OutPath: FragmentDurationMs:0 FragmentNum:0 DeleteThreshold:0 CleanupMode:0} SubSessionTimeoutMs:0 SubSessionHashKey:} HttptsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} RtspConfig:{Enable:false Addr: RtspsEnable:false RtspsAddr: RtspsCertFile: RtspsKeyFile: OutWaitKeyFrameFlag:false WsRtspEnable:false WsRtspAddr: ServerAuthConfig:{AuthEnable:false AuthMethod:0 UserName: PassWord:}} RecordConfig:{EnableFlv:false FlvOutPath: EnableMpegts:false MpegtsOutPath:} RelayPushConfig:{Enable:false AddrList:[]} StaticRelayPullConfig:{Enable:false Addr:} HttpApiConfig:{Enable:false Addr:} ServerId: HttpNotifyConfig:{Enable:false UpdateIntervalSec:0 OnServerStart: OnUpdate: OnPubStart: OnPubStop: OnSubStart: OnSubStop: OnRelayPullStart: OnRelayPullStop: OnRtmpConnect: OnHlsMakeTs:} SimpleAuthConfig:{Key: DangerousLalSecret: PubRtmpEnable:false SubRtmpEnable:false SubHttpflvEnable:false SubHttptsEnable:false PubRtspEnable:false SubRtspEnable:false HlsM3u8Enable:false} PprofConfig:{Enable:false Addr:} LogConfig:{Level:1 Filename:./logs/lalserver.log IsToStdout:true IsRotateDaily:true IsRotateHourly:false ShortFileFlag:true TimestampFlag:true TimestampWithMsFlag:true LevelFlag:true AssertBehavior:1 HookBackendOutFn:} DebugConfig:{LogGroupIntervalSec:0 LogGroupMaxGroupNum:0 LogGroupMaxSubNumPerGroup:0}} - config.go:346 -2026/04/23 10:37:23.155229  INFO  start: 2026-04-23 10:37:23.133 - base.go:35 -2026/04/23 10:37:23.155229  INFO  wd: F:\开源\go\lalmi\lalmax\server - base.go:36 -2026/04/23 10:37:23.155229  INFO  args: C:\Users\ADMINI~1\AppData\Local\Temp\go-build1390121107\b363\server.test.exe -test.testlogfile=C:\Users\ADMINI~1\AppData\Local\Temp\go-build1390121107\b363\testlog.txt -test.paniconexit0 -test.timeout=10m0s - base.go:37 -2026/04/23 10:37:23.155229  INFO  bininfo: GitTag=unknown. GitCommitLog=unknown. GitStatus=unknown. BuildTime=unknown. GoVersion=unknown. runtime=windows/amd64. - base.go:38 -2026/04/23 10:37:23.155229  INFO  version: lal v0.37.4 (github.com/q191201771/lal) - base.go:39 -2026/04/23 10:37:23.155229  INFO  github: https://github.com/q191201771/lal - base.go:40 -2026/04/23 10:37:23.155229  INFO  doc: https://pengrl.com/lal - base.go:41 -2026/04/23 10:37:23.155229  INFO lalmax http listen. addr=:52349 - server.go:103 -2026/04/23 10:37:23.155739  INFO [GROUP1] lifecycle new group. group=0xc000091888, appName=, streamName=test - group__.go:185 -2026/04/23 10:37:23.155739  INFO [CUSTOMIZEPUB1] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:37:23.155739 DEBUG [GROUP1] [CUSTOMIZEPUB1] add customize pub session into group. - group__in.go:33 -2026/04/23 10:37:23.155739  INFO create group, uniqueKey:, streamKey:test - group.go:108 -2026/04/23 10:37:23.155739  INFO SetGroup, streamKey:test - group_manager.go:105 -2026/04/23 10:37:23.156259  INFO AddSubscriber, streamKey:test, subscriberId:consumer1, protocol:LALMAX - group.go:237 -2026/04/23 10:37:23.156259  INFO [GROUP2] lifecycle new group. group=0xc000091c08, appName=, streamName=notify_test - group__.go:185 -2026/04/23 10:37:23.156259  INFO [CUSTOMIZEPUB2] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:37:23.156259 DEBUG [GROUP2] [CUSTOMIZEPUB2] add customize pub session into group. - group__in.go:33 -2026/04/23 10:37:23.156259  INFO create group, uniqueKey:, streamKey:notify_test - group.go:108 -2026/04/23 10:37:23.156259  INFO SetGroup, streamKey:notify_test - group_manager.go:105 -2026/04/23 10:37:23.156259  INFO AddSubscriber, streamKey:notify_test, subscriberId:consumer_notify, protocol:LALMAX - group.go:237 -2026/04/23 10:37:23.156259 ERROR http notify post error. err=Post "http://127.0.0.1:55559/on_update": dial tcp 127.0.0.1:55559: connectex: No connection could be made because the target machine actively refused it., url=http://127.0.0.1:55559/on_update, info={EventCommonInfo:{ServerId:} Groups:[]} - http_notify.go:216 -2026/04/23 10:37:26.156615  INFO http api start rtp pub. req info={StreamName:rtp_pub_test Port:0 TimeoutMs:0 IsTcpFlag:0 DebugDumpPacket:} - router.go:245 -2026/04/23 10:37:26.156615  INFO http api stop rtp pub. stream_name=rtp_pub_test, session_id= - router.go:271 -2026/04/23 10:39:11.914284  INFO initial log succ. - config.go:249 -2026/04/23 10:39:11.914284  INFO  - __ ___ __ - / / / | / / - / / / /| | / / - / /___/ ___ |/ /___ -/_____/_/ |_/_____/ - - config.go:252 -2026/04/23 10:39:11.914284  WARN config version invalid. conf version of lalserver=v0.4.1, conf version of config file= - config.go:262 -2026/04/23 10:39:11.914284  WARN config some fields do not exist which have been set to the zero value. fields=[conf_version rtmp.addr rtmp.rtmps_enable rtmp.rtmps_addr rtmp.rtmps_cert_file rtmp.rtmps_key_file rtmp.gop_num rtmp.single_gop_max_frame_num rtmp.merge_write_size in_session.add_dummy_audio_enable in_session.add_dummy_audio_wait_audio_ms httpflv.enable httpflv.enable_https httpflv.url_pattern httpflv.gop_num httpflv.single_gop_max_frame_num hls.enable hls.enable_https hls.url_pattern hls.use_memory_as_disk_flag hls.out_path hls.fragment_duration_ms hls.fragment_num hls.delete_threshold hls.cleanup_mode hls.sub_session_timeout_ms hls.sub_session_hash_key httpts.enable httpts.enable_https httpts.url_pattern httpts.gop_num httpts.single_gop_max_frame_num rtsp.addr rtsp.rtsps_enable rtsp.rtsps_addr rtsp.rtsps_cert_file rtsp.rtsps_key_file rtsp.out_wait_key_frame_flag rtsp.ws_rtsp_enable rtsp.ws_rtsp_addr rtsp.auth_enable rtsp.auth_method rtsp.username rtsp.password record.enable_flv record.flv_out_path record.enable_mpegts record.mpegts_out_path relay_push.enable relay_push.addr_list static_relay_pull.enable static_relay_pull.addr http_api.addr server_id http_notify.enable http_notify.update_interval_sec http_notify.on_server_start http_notify.on_update http_notify.on_pub_start http_notify.on_pub_stop http_notify.on_sub_start http_notify.on_sub_stop http_notify.on_relay_pull_start http_notify.on_relay_pull_stop http_notify.on_rtmp_connect http_notify.on_hls_make_ts simple_auth.key simple_auth.dangerous_lal_secret simple_auth.pub_rtmp_enable simple_auth.sub_rtmp_enable simple_auth.sub_httpflv_enable simple_auth.sub_httpts_enable simple_auth.pub_rtsp_enable simple_auth.sub_rtsp_enable simple_auth.hls_m3u8_enable pprof.addr debug.log_group_interval_sec debug.log_group_max_group_num debug.log_group_max_sub_num_per_group] - config.go:278 -2026/04/23 10:39:11.914284  WARN config some log fields do not exist which have been set to default value. log.level=LevelDebug, log.filename=./logs/lalserver.log, log.is_to_stdout=true, log.is_rotate_daily=true, log.short_file_flag=true, log.timestamp_flag=true, log.timestamp_with_ms_flag=true, log.level_flag=true, log.assert_behavior=AssertError - config.go:283 -2026/04/23 10:39:11.914284  INFO load conf succ. raw content={"rtmp":{"enable":false},"rtsp":{"enable":false},"http_api":{"enable":false},"pprof":{"enable":false}} parsed=&{ConfVersion: RtmpConfig:{Enable:false Addr: RtmpsEnable:false RtmpsAddr: RtmpsCertFile: RtmpsKeyFile: GopNum:0 SingleGopMaxFrameNum:0 MergeWriteSize:0} InSessionConfig:{AddDummyAudioEnable:false AddDummyAudioWaitAudioMs:0} DefaultHttpConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:}} HttpflvConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} HlsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} UseMemoryAsDiskFlag:false MuxerConfig:{OutPath: FragmentDurationMs:0 FragmentNum:0 DeleteThreshold:0 CleanupMode:0} SubSessionTimeoutMs:0 SubSessionHashKey:} HttptsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} RtspConfig:{Enable:false Addr: RtspsEnable:false RtspsAddr: RtspsCertFile: RtspsKeyFile: OutWaitKeyFrameFlag:false WsRtspEnable:false WsRtspAddr: ServerAuthConfig:{AuthEnable:false AuthMethod:0 UserName: PassWord:}} RecordConfig:{EnableFlv:false FlvOutPath: EnableMpegts:false MpegtsOutPath:} RelayPushConfig:{Enable:false AddrList:[]} StaticRelayPullConfig:{Enable:false Addr:} HttpApiConfig:{Enable:false Addr:} ServerId: HttpNotifyConfig:{Enable:false UpdateIntervalSec:0 OnServerStart: OnUpdate: OnPubStart: OnPubStop: OnSubStart: OnSubStop: OnRelayPullStart: OnRelayPullStop: OnRtmpConnect: OnHlsMakeTs:} SimpleAuthConfig:{Key: DangerousLalSecret: PubRtmpEnable:false SubRtmpEnable:false SubHttpflvEnable:false SubHttptsEnable:false PubRtspEnable:false SubRtspEnable:false HlsM3u8Enable:false} PprofConfig:{Enable:false Addr:} LogConfig:{Level:1 Filename:./logs/lalserver.log IsToStdout:true IsRotateDaily:true IsRotateHourly:false ShortFileFlag:true TimestampFlag:true TimestampWithMsFlag:true LevelFlag:true AssertBehavior:1 HookBackendOutFn:} DebugConfig:{LogGroupIntervalSec:0 LogGroupMaxGroupNum:0 LogGroupMaxSubNumPerGroup:0}} - config.go:346 -2026/04/23 10:39:11.914284  INFO  start: 2026-04-23 10:39:11.897 - base.go:35 -2026/04/23 10:39:11.915156  INFO  wd: F:\开源\go\lalmi\lalmax\server - base.go:36 -2026/04/23 10:39:11.915156  INFO  args: C:\Users\ADMINI~1\AppData\Local\Temp\go-build2037119015\b363\server.test.exe -test.testlogfile=C:\Users\ADMINI~1\AppData\Local\Temp\go-build2037119015\b363\testlog.txt -test.paniconexit0 -test.timeout=10m0s - base.go:37 -2026/04/23 10:39:11.915156  INFO  bininfo: GitTag=unknown. GitCommitLog=unknown. GitStatus=unknown. BuildTime=unknown. GoVersion=unknown. runtime=windows/amd64. - base.go:38 -2026/04/23 10:39:11.915156  INFO  version: lal v0.37.4 (github.com/q191201771/lal) - base.go:39 -2026/04/23 10:39:11.915156  INFO  github: https://github.com/q191201771/lal - base.go:40 -2026/04/23 10:39:11.915156  INFO  doc: https://pengrl.com/lal - base.go:41 -2026/04/23 10:39:11.915156  INFO lalmax http listen. addr=:52349 - server.go:103 -2026/04/23 10:39:11.915156  INFO [GROUP1] lifecycle new group. group=0xc0002e0708, appName=, streamName=test - group__.go:185 -2026/04/23 10:39:11.915156  INFO [CUSTOMIZEPUB1] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:39:11.915156 DEBUG [GROUP1] [CUSTOMIZEPUB1] add customize pub session into group. - group__in.go:33 -2026/04/23 10:39:11.915156  INFO create group, uniqueKey:, streamKey:test - group.go:108 -2026/04/23 10:39:11.915156  INFO SetGroup, streamKey:test - group_manager.go:105 -2026/04/23 10:39:11.915912  INFO AddSubscriber, streamKey:test, subscriberId:consumer1, protocol:LALMAX - group.go:237 -2026/04/23 10:39:11.915912  INFO [GROUP2] lifecycle new group. group=0xc0002e0a88, appName=, streamName=notify_test - group__.go:185 -2026/04/23 10:39:11.915912  INFO [CUSTOMIZEPUB2] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:39:11.915912 DEBUG [GROUP2] [CUSTOMIZEPUB2] add customize pub session into group. - group__in.go:33 -2026/04/23 10:39:11.915912  INFO create group, uniqueKey:, streamKey:notify_test - group.go:108 -2026/04/23 10:39:11.915912  INFO SetGroup, streamKey:notify_test - group_manager.go:105 -2026/04/23 10:39:11.915912  INFO AddSubscriber, streamKey:notify_test, subscriberId:consumer_notify, protocol:LALMAX - group.go:237 -2026/04/23 10:39:11.915912 ERROR http notify post error. err=Post "http://127.0.0.1:55559/on_update": dial tcp 127.0.0.1:55559: connectex: No connection could be made because the target machine actively refused it., url=http://127.0.0.1:55559/on_update, info={EventCommonInfo:{ServerId:} Groups:[]} - http_notify.go:216 -2026/04/23 10:39:14.915985  INFO http api start rtp pub. req info={StreamName:rtp_pub_test Port:0 TimeoutMs:0 IsTcpFlag:0 DebugDumpPacket:} - router.go:245 -2026/04/23 10:39:14.916290  INFO http api stop rtp pub. stream_name=rtp_pub_test, session_id= - router.go:271 -2026/04/23 10:43:21.196284  INFO initial log succ. - config.go:249 -2026/04/23 10:43:21.196284  INFO  - __ ___ __ - / / / | / / - / / / /| | / / - / /___/ ___ |/ /___ -/_____/_/ |_/_____/ - - config.go:252 -2026/04/23 10:43:21.196284  WARN config version invalid. conf version of lalserver=v0.4.1, conf version of config file= - config.go:262 -2026/04/23 10:43:21.196284  WARN config some fields do not exist which have been set to the zero value. fields=[conf_version rtmp.addr rtmp.rtmps_enable rtmp.rtmps_addr rtmp.rtmps_cert_file rtmp.rtmps_key_file rtmp.gop_num rtmp.single_gop_max_frame_num rtmp.merge_write_size in_session.add_dummy_audio_enable in_session.add_dummy_audio_wait_audio_ms httpflv.enable httpflv.enable_https httpflv.url_pattern httpflv.gop_num httpflv.single_gop_max_frame_num hls.enable hls.enable_https hls.url_pattern hls.use_memory_as_disk_flag hls.out_path hls.fragment_duration_ms hls.fragment_num hls.delete_threshold hls.cleanup_mode hls.sub_session_timeout_ms hls.sub_session_hash_key httpts.enable httpts.enable_https httpts.url_pattern httpts.gop_num httpts.single_gop_max_frame_num rtsp.addr rtsp.rtsps_enable rtsp.rtsps_addr rtsp.rtsps_cert_file rtsp.rtsps_key_file rtsp.out_wait_key_frame_flag rtsp.ws_rtsp_enable rtsp.ws_rtsp_addr rtsp.auth_enable rtsp.auth_method rtsp.username rtsp.password record.enable_flv record.flv_out_path record.enable_mpegts record.mpegts_out_path relay_push.enable relay_push.addr_list static_relay_pull.enable static_relay_pull.addr http_api.addr server_id http_notify.enable http_notify.update_interval_sec http_notify.on_server_start http_notify.on_update http_notify.on_pub_start http_notify.on_pub_stop http_notify.on_sub_start http_notify.on_sub_stop http_notify.on_relay_pull_start http_notify.on_relay_pull_stop http_notify.on_rtmp_connect http_notify.on_hls_make_ts simple_auth.key simple_auth.dangerous_lal_secret simple_auth.pub_rtmp_enable simple_auth.sub_rtmp_enable simple_auth.sub_httpflv_enable simple_auth.sub_httpts_enable simple_auth.pub_rtsp_enable simple_auth.sub_rtsp_enable simple_auth.hls_m3u8_enable pprof.addr debug.log_group_interval_sec debug.log_group_max_group_num debug.log_group_max_sub_num_per_group] - config.go:278 -2026/04/23 10:43:21.196284  WARN config some log fields do not exist which have been set to default value. log.level=LevelDebug, log.filename=./logs/lalserver.log, log.is_to_stdout=true, log.is_rotate_daily=true, log.short_file_flag=true, log.timestamp_flag=true, log.timestamp_with_ms_flag=true, log.level_flag=true, log.assert_behavior=AssertError - config.go:283 -2026/04/23 10:43:21.196284  INFO load conf succ. raw content={"rtmp":{"enable":false},"rtsp":{"enable":false},"http_api":{"enable":false},"pprof":{"enable":false}} parsed=&{ConfVersion: RtmpConfig:{Enable:false Addr: RtmpsEnable:false RtmpsAddr: RtmpsCertFile: RtmpsKeyFile: GopNum:0 SingleGopMaxFrameNum:0 MergeWriteSize:0} InSessionConfig:{AddDummyAudioEnable:false AddDummyAudioWaitAudioMs:0} DefaultHttpConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:}} HttpflvConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} HlsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} UseMemoryAsDiskFlag:false MuxerConfig:{OutPath: FragmentDurationMs:0 FragmentNum:0 DeleteThreshold:0 CleanupMode:0} SubSessionTimeoutMs:0 SubSessionHashKey:} HttptsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} RtspConfig:{Enable:false Addr: RtspsEnable:false RtspsAddr: RtspsCertFile: RtspsKeyFile: OutWaitKeyFrameFlag:false WsRtspEnable:false WsRtspAddr: ServerAuthConfig:{AuthEnable:false AuthMethod:0 UserName: PassWord:}} RecordConfig:{EnableFlv:false FlvOutPath: EnableMpegts:false MpegtsOutPath:} RelayPushConfig:{Enable:false AddrList:[]} StaticRelayPullConfig:{Enable:false Addr:} HttpApiConfig:{Enable:false Addr:} ServerId: HttpNotifyConfig:{Enable:false UpdateIntervalSec:0 OnServerStart: OnUpdate: OnPubStart: OnPubStop: OnSubStart: OnSubStop: OnRelayPullStart: OnRelayPullStop: OnRtmpConnect: OnHlsMakeTs:} SimpleAuthConfig:{Key: DangerousLalSecret: PubRtmpEnable:false SubRtmpEnable:false SubHttpflvEnable:false SubHttptsEnable:false PubRtspEnable:false SubRtspEnable:false HlsM3u8Enable:false} PprofConfig:{Enable:false Addr:} LogConfig:{Level:1 Filename:./logs/lalserver.log IsToStdout:true IsRotateDaily:true IsRotateHourly:false ShortFileFlag:true TimestampFlag:true TimestampWithMsFlag:true LevelFlag:true AssertBehavior:1 HookBackendOutFn:} DebugConfig:{LogGroupIntervalSec:0 LogGroupMaxGroupNum:0 LogGroupMaxSubNumPerGroup:0}} - config.go:346 -2026/04/23 10:43:21.196284  INFO  start: 2026-04-23 10:43:21.177 - base.go:35 -2026/04/23 10:43:21.196284  INFO  wd: F:\开源\go\lalmi\lalmax\server - base.go:36 -2026/04/23 10:43:21.196284  INFO  args: C:\Users\ADMINI~1\AppData\Local\Temp\go-build3820063322\b363\server.test.exe -test.testlogfile=C:\Users\ADMINI~1\AppData\Local\Temp\go-build3820063322\b363\testlog.txt -test.paniconexit0 -test.timeout=10m0s - base.go:37 -2026/04/23 10:43:21.196284  INFO  bininfo: GitTag=unknown. GitCommitLog=unknown. GitStatus=unknown. BuildTime=unknown. GoVersion=unknown. runtime=windows/amd64. - base.go:38 -2026/04/23 10:43:21.196284  INFO  version: lal v0.37.4 (github.com/q191201771/lal) - base.go:39 -2026/04/23 10:43:21.196284  INFO  github: https://github.com/q191201771/lal - base.go:40 -2026/04/23 10:43:21.196284  INFO  doc: https://pengrl.com/lal - base.go:41 -2026/04/23 10:43:21.196284  INFO lalmax http listen. addr=:52349 - server.go:103 -2026/04/23 10:43:21.196284  INFO [GROUP1] lifecycle new group. group=0xc000091888, appName=, streamName=test - group__.go:185 -2026/04/23 10:43:21.196284  INFO [CUSTOMIZEPUB1] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:43:21.196284 DEBUG [GROUP1] [CUSTOMIZEPUB1] add customize pub session into group. - group__in.go:33 -2026/04/23 10:43:21.196284  INFO create group, uniqueKey:, streamKey:test - group.go:108 -2026/04/23 10:43:21.196284  INFO SetGroup, streamKey:test - group_manager.go:105 -2026/04/23 10:43:21.197284  INFO AddSubscriber, streamKey:test, subscriberId:consumer1, protocol:LALMAX - group.go:237 -2026/04/23 10:43:21.197284  INFO [GROUP2] lifecycle new group. group=0xc000091c08, appName=, streamName=notify_test - group__.go:185 -2026/04/23 10:43:21.197284  INFO [CUSTOMIZEPUB2] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:43:21.197284 DEBUG [GROUP2] [CUSTOMIZEPUB2] add customize pub session into group. - group__in.go:33 -2026/04/23 10:43:21.197284  INFO create group, uniqueKey:, streamKey:notify_test - group.go:108 -2026/04/23 10:43:21.197284  INFO SetGroup, streamKey:notify_test - group_manager.go:105 -2026/04/23 10:43:21.197284  INFO AddSubscriber, streamKey:notify_test, subscriberId:consumer_notify, protocol:LALMAX - group.go:237 -2026/04/23 10:43:21.197284 ERROR http notify post error. err=Post "http://127.0.0.1:55559/on_update": dial tcp 127.0.0.1:55559: connectex: No connection could be made because the target machine actively refused it., url=http://127.0.0.1:55559/on_update, info={EventCommonInfo:{ServerId:} Groups:[]} - http_notify.go:216 -2026/04/23 10:43:24.197564  INFO http api start rtp pub. req info={StreamName:rtp_pub_test Port:0 TimeoutMs:0 IsTcpFlag:0 DebugDumpPacket:} - router.go:245 -2026/04/23 10:43:24.197820  INFO http api stop rtp pub. stream_name=rtp_pub_test, session_id= - router.go:271 -2026/04/23 10:46:51.244739  INFO initial log succ. - config.go:249 -2026/04/23 10:46:51.244739  INFO  - __ ___ __ - / / / | / / - / / / /| | / / - / /___/ ___ |/ /___ -/_____/_/ |_/_____/ - - config.go:252 -2026/04/23 10:46:51.244739  WARN config version invalid. conf version of lalserver=v0.4.1, conf version of config file= - config.go:262 -2026/04/23 10:46:51.244739  WARN config some fields do not exist which have been set to the zero value. fields=[conf_version rtmp.addr rtmp.rtmps_enable rtmp.rtmps_addr rtmp.rtmps_cert_file rtmp.rtmps_key_file rtmp.gop_num rtmp.single_gop_max_frame_num rtmp.merge_write_size in_session.add_dummy_audio_enable in_session.add_dummy_audio_wait_audio_ms httpflv.enable httpflv.enable_https httpflv.url_pattern httpflv.gop_num httpflv.single_gop_max_frame_num hls.enable hls.enable_https hls.url_pattern hls.use_memory_as_disk_flag hls.out_path hls.fragment_duration_ms hls.fragment_num hls.delete_threshold hls.cleanup_mode hls.sub_session_timeout_ms hls.sub_session_hash_key httpts.enable httpts.enable_https httpts.url_pattern httpts.gop_num httpts.single_gop_max_frame_num rtsp.addr rtsp.rtsps_enable rtsp.rtsps_addr rtsp.rtsps_cert_file rtsp.rtsps_key_file rtsp.out_wait_key_frame_flag rtsp.ws_rtsp_enable rtsp.ws_rtsp_addr rtsp.auth_enable rtsp.auth_method rtsp.username rtsp.password record.enable_flv record.flv_out_path record.enable_mpegts record.mpegts_out_path relay_push.enable relay_push.addr_list static_relay_pull.enable static_relay_pull.addr http_api.addr server_id http_notify.enable http_notify.update_interval_sec http_notify.on_server_start http_notify.on_update http_notify.on_pub_start http_notify.on_pub_stop http_notify.on_sub_start http_notify.on_sub_stop http_notify.on_relay_pull_start http_notify.on_relay_pull_stop http_notify.on_rtmp_connect http_notify.on_hls_make_ts simple_auth.key simple_auth.dangerous_lal_secret simple_auth.pub_rtmp_enable simple_auth.sub_rtmp_enable simple_auth.sub_httpflv_enable simple_auth.sub_httpts_enable simple_auth.pub_rtsp_enable simple_auth.sub_rtsp_enable simple_auth.hls_m3u8_enable pprof.addr debug.log_group_interval_sec debug.log_group_max_group_num debug.log_group_max_sub_num_per_group] - config.go:278 -2026/04/23 10:46:51.244739  WARN config some log fields do not exist which have been set to default value. log.level=LevelDebug, log.filename=./logs/lalserver.log, log.is_to_stdout=true, log.is_rotate_daily=true, log.short_file_flag=true, log.timestamp_flag=true, log.timestamp_with_ms_flag=true, log.level_flag=true, log.assert_behavior=AssertError - config.go:283 -2026/04/23 10:46:51.244739  INFO load conf succ. raw content={"rtmp":{"enable":false},"rtsp":{"enable":false},"http_api":{"enable":false},"pprof":{"enable":false}} parsed=&{ConfVersion: RtmpConfig:{Enable:false Addr: RtmpsEnable:false RtmpsAddr: RtmpsCertFile: RtmpsKeyFile: GopNum:0 SingleGopMaxFrameNum:0 MergeWriteSize:0} InSessionConfig:{AddDummyAudioEnable:false AddDummyAudioWaitAudioMs:0} DefaultHttpConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:}} HttpflvConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} HlsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} UseMemoryAsDiskFlag:false MuxerConfig:{OutPath: FragmentDurationMs:0 FragmentNum:0 DeleteThreshold:0 CleanupMode:0} SubSessionTimeoutMs:0 SubSessionHashKey:} HttptsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} RtspConfig:{Enable:false Addr: RtspsEnable:false RtspsAddr: RtspsCertFile: RtspsKeyFile: OutWaitKeyFrameFlag:false WsRtspEnable:false WsRtspAddr: ServerAuthConfig:{AuthEnable:false AuthMethod:0 UserName: PassWord:}} RecordConfig:{EnableFlv:false FlvOutPath: EnableMpegts:false MpegtsOutPath:} RelayPushConfig:{Enable:false AddrList:[]} StaticRelayPullConfig:{Enable:false Addr:} HttpApiConfig:{Enable:false Addr:} ServerId: HttpNotifyConfig:{Enable:false UpdateIntervalSec:0 OnServerStart: OnUpdate: OnPubStart: OnPubStop: OnSubStart: OnSubStop: OnRelayPullStart: OnRelayPullStop: OnRtmpConnect: OnHlsMakeTs:} SimpleAuthConfig:{Key: DangerousLalSecret: PubRtmpEnable:false SubRtmpEnable:false SubHttpflvEnable:false SubHttptsEnable:false PubRtspEnable:false SubRtspEnable:false HlsM3u8Enable:false} PprofConfig:{Enable:false Addr:} LogConfig:{Level:1 Filename:./logs/lalserver.log IsToStdout:true IsRotateDaily:true IsRotateHourly:false ShortFileFlag:true TimestampFlag:true TimestampWithMsFlag:true LevelFlag:true AssertBehavior:1 HookBackendOutFn:} DebugConfig:{LogGroupIntervalSec:0 LogGroupMaxGroupNum:0 LogGroupMaxSubNumPerGroup:0}} - config.go:346 -2026/04/23 10:46:51.244739  INFO  start: 2026-04-23 10:46:51.225 - base.go:35 -2026/04/23 10:46:51.244739  INFO  wd: F:\开源\go\lalmi\lalmax\server - base.go:36 -2026/04/23 10:46:51.244739  INFO  args: C:\Users\ADMINI~1\AppData\Local\Temp\go-build710474692\b363\server.test.exe -test.testlogfile=C:\Users\ADMINI~1\AppData\Local\Temp\go-build710474692\b363\testlog.txt -test.paniconexit0 -test.timeout=10m0s - base.go:37 -2026/04/23 10:46:51.244739  INFO  bininfo: GitTag=unknown. GitCommitLog=unknown. GitStatus=unknown. BuildTime=unknown. GoVersion=unknown. runtime=windows/amd64. - base.go:38 -2026/04/23 10:46:51.244739  INFO  version: lal v0.37.4 (github.com/q191201771/lal) - base.go:39 -2026/04/23 10:46:51.244739  INFO  github: https://github.com/q191201771/lal - base.go:40 -2026/04/23 10:46:51.244739  INFO  doc: https://pengrl.com/lal - base.go:41 -2026/04/23 10:46:51.245259  INFO lalmax http listen. addr=:52349 - server.go:103 -2026/04/23 10:46:51.245259  INFO [GROUP1] lifecycle new group. group=0xc000113888, appName=, streamName=test - group__.go:185 -2026/04/23 10:46:51.245259  INFO [CUSTOMIZEPUB1] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:46:51.245259 DEBUG [GROUP1] [CUSTOMIZEPUB1] add customize pub session into group. - group__in.go:33 -2026/04/23 10:46:51.245259  INFO create group, uniqueKey:, streamKey:test - group.go:108 -2026/04/23 10:46:51.245259  INFO SetGroup, streamKey:test - group_manager.go:105 -2026/04/23 10:46:51.245779  INFO AddSubscriber, streamKey:test, subscriberId:consumer1, protocol:LALMAX - group.go:237 -2026/04/23 10:46:51.245779  INFO [GROUP2] lifecycle new group. group=0xc000113c08, appName=, streamName=notify_test - group__.go:185 -2026/04/23 10:46:51.245779  INFO [CUSTOMIZEPUB2] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:46:51.245779 DEBUG [GROUP2] [CUSTOMIZEPUB2] add customize pub session into group. - group__in.go:33 -2026/04/23 10:46:51.245779  INFO create group, uniqueKey:, streamKey:notify_test - group.go:108 -2026/04/23 10:46:51.245779  INFO SetGroup, streamKey:notify_test - group_manager.go:105 -2026/04/23 10:46:51.245779  INFO AddSubscriber, streamKey:notify_test, subscriberId:consumer_notify, protocol:LALMAX - group.go:237 -2026/04/23 10:46:51.246301 ERROR http notify post error. err=Post "http://127.0.0.1:55559/on_update": dial tcp 127.0.0.1:55559: connectex: No connection could be made because the target machine actively refused it., url=http://127.0.0.1:55559/on_update, info={EventCommonInfo:{ServerId:} Groups:[]} - http_notify.go:216 -2026/04/23 10:46:54.246259  INFO http api start rtp pub. req info={StreamName:rtp_pub_test Port:0 TimeoutMs:0 IsTcpFlag:0 DebugDumpPacket:} - router.go:245 -2026/04/23 10:46:54.246564  INFO http api stop rtp pub. stream_name=rtp_pub_test, session_id= - router.go:271 -2026/04/23 10:56:11.867506  INFO initial log succ. - config.go:249 -2026/04/23 10:56:11.867506  INFO  - __ ___ __ - / / / | / / - / / / /| | / / - / /___/ ___ |/ /___ -/_____/_/ |_/_____/ - - config.go:252 -2026/04/23 10:56:11.867506  WARN config version invalid. conf version of lalserver=v0.4.1, conf version of config file= - config.go:262 -2026/04/23 10:56:11.867506  WARN config some fields do not exist which have been set to the zero value. fields=[conf_version rtmp.addr rtmp.rtmps_enable rtmp.rtmps_addr rtmp.rtmps_cert_file rtmp.rtmps_key_file rtmp.gop_num rtmp.single_gop_max_frame_num rtmp.merge_write_size in_session.add_dummy_audio_enable in_session.add_dummy_audio_wait_audio_ms httpflv.enable httpflv.enable_https httpflv.url_pattern httpflv.gop_num httpflv.single_gop_max_frame_num hls.enable hls.enable_https hls.url_pattern hls.use_memory_as_disk_flag hls.out_path hls.fragment_duration_ms hls.fragment_num hls.delete_threshold hls.cleanup_mode hls.sub_session_timeout_ms hls.sub_session_hash_key httpts.enable httpts.enable_https httpts.url_pattern httpts.gop_num httpts.single_gop_max_frame_num rtsp.addr rtsp.rtsps_enable rtsp.rtsps_addr rtsp.rtsps_cert_file rtsp.rtsps_key_file rtsp.out_wait_key_frame_flag rtsp.ws_rtsp_enable rtsp.ws_rtsp_addr rtsp.auth_enable rtsp.auth_method rtsp.username rtsp.password record.enable_flv record.flv_out_path record.enable_mpegts record.mpegts_out_path relay_push.enable relay_push.addr_list static_relay_pull.enable static_relay_pull.addr http_api.addr server_id http_notify.enable http_notify.update_interval_sec http_notify.on_server_start http_notify.on_update http_notify.on_pub_start http_notify.on_pub_stop http_notify.on_sub_start http_notify.on_sub_stop http_notify.on_relay_pull_start http_notify.on_relay_pull_stop http_notify.on_rtmp_connect http_notify.on_hls_make_ts simple_auth.key simple_auth.dangerous_lal_secret simple_auth.pub_rtmp_enable simple_auth.sub_rtmp_enable simple_auth.sub_httpflv_enable simple_auth.sub_httpts_enable simple_auth.pub_rtsp_enable simple_auth.sub_rtsp_enable simple_auth.hls_m3u8_enable pprof.addr debug.log_group_interval_sec debug.log_group_max_group_num debug.log_group_max_sub_num_per_group] - config.go:278 -2026/04/23 10:56:11.867506  WARN config some log fields do not exist which have been set to default value. log.level=LevelDebug, log.filename=./logs/lalserver.log, log.is_to_stdout=true, log.is_rotate_daily=true, log.short_file_flag=true, log.timestamp_flag=true, log.timestamp_with_ms_flag=true, log.level_flag=true, log.assert_behavior=AssertError - config.go:283 -2026/04/23 10:56:11.867506  INFO load conf succ. raw content={"rtmp":{"enable":false},"rtsp":{"enable":false},"http_api":{"enable":false},"pprof":{"enable":false}} parsed=&{ConfVersion: RtmpConfig:{Enable:false Addr: RtmpsEnable:false RtmpsAddr: RtmpsCertFile: RtmpsKeyFile: GopNum:0 SingleGopMaxFrameNum:0 MergeWriteSize:0} InSessionConfig:{AddDummyAudioEnable:false AddDummyAudioWaitAudioMs:0} DefaultHttpConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:}} HttpflvConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} HlsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} UseMemoryAsDiskFlag:false MuxerConfig:{OutPath: FragmentDurationMs:0 FragmentNum:0 DeleteThreshold:0 CleanupMode:0} SubSessionTimeoutMs:0 SubSessionHashKey:} HttptsConfig:{CommonHttpServerConfig:{CommonHttpAddrConfig:{HttpListenAddr: HttpsListenAddr: HttpsCertFile: HttpsKeyFile:} Enable:false EnableHttps:false UrlPattern:} GopNum:0 SingleGopMaxFrameNum:0} RtspConfig:{Enable:false Addr: RtspsEnable:false RtspsAddr: RtspsCertFile: RtspsKeyFile: OutWaitKeyFrameFlag:false WsRtspEnable:false WsRtspAddr: ServerAuthConfig:{AuthEnable:false AuthMethod:0 UserName: PassWord:}} RecordConfig:{EnableFlv:false FlvOutPath: EnableMpegts:false MpegtsOutPath:} RelayPushConfig:{Enable:false AddrList:[]} StaticRelayPullConfig:{Enable:false Addr:} HttpApiConfig:{Enable:false Addr:} ServerId: HttpNotifyConfig:{Enable:false UpdateIntervalSec:0 OnServerStart: OnUpdate: OnPubStart: OnPubStop: OnSubStart: OnSubStop: OnRelayPullStart: OnRelayPullStop: OnRtmpConnect: OnHlsMakeTs:} SimpleAuthConfig:{Key: DangerousLalSecret: PubRtmpEnable:false SubRtmpEnable:false SubHttpflvEnable:false SubHttptsEnable:false PubRtspEnable:false SubRtspEnable:false HlsM3u8Enable:false} PprofConfig:{Enable:false Addr:} LogConfig:{Level:1 Filename:./logs/lalserver.log IsToStdout:true IsRotateDaily:true IsRotateHourly:false ShortFileFlag:true TimestampFlag:true TimestampWithMsFlag:true LevelFlag:true AssertBehavior:1 HookBackendOutFn:} DebugConfig:{LogGroupIntervalSec:0 LogGroupMaxGroupNum:0 LogGroupMaxSubNumPerGroup:0}} - config.go:346 -2026/04/23 10:56:11.867506  INFO  start: 2026-04-23 10:56:11.849 - base.go:35 -2026/04/23 10:56:11.867506  INFO  wd: F:\开源\go\lalmi\lalmax\server - base.go:36 -2026/04/23 10:56:11.867506  INFO  args: C:\Users\ADMINI~1\AppData\Local\Temp\go-build3560235915\b364\server.test.exe -test.testlogfile=C:\Users\ADMINI~1\AppData\Local\Temp\go-build3560235915\b364\testlog.txt -test.paniconexit0 -test.timeout=10m0s - base.go:37 -2026/04/23 10:56:11.867506  INFO  bininfo: GitTag=unknown. GitCommitLog=unknown. GitStatus=unknown. BuildTime=unknown. GoVersion=unknown. runtime=windows/amd64. - base.go:38 -2026/04/23 10:56:11.867506  INFO  version: lal v0.37.4 (github.com/q191201771/lal) - base.go:39 -2026/04/23 10:56:11.867506  INFO  github: https://github.com/q191201771/lal - base.go:40 -2026/04/23 10:56:11.867506  INFO  doc: https://pengrl.com/lal - base.go:41 -2026/04/23 10:56:11.867506  INFO lalmax http listen. addr=:52349 - server.go:103 -2026/04/23 10:56:11.867506  INFO [GROUP1] lifecycle new group. group=0xc000091888, appName=, streamName=test - group__.go:185 -2026/04/23 10:56:11.867506  INFO [CUSTOMIZEPUB1] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:56:11.867506 DEBUG [GROUP1] [CUSTOMIZEPUB1] add customize pub session into group. - group__in.go:33 -2026/04/23 10:56:11.867506  INFO create group, uniqueKey:, streamKey:test - group.go:108 -2026/04/23 10:56:11.867506  INFO SetGroup, streamKey:test - group_manager.go:105 -2026/04/23 10:56:11.868976  INFO AddSubscriber, streamKey:test, subscriberId:consumer1, protocol:LALMAX - group.go:237 -2026/04/23 10:56:11.868976  INFO [GROUP2] lifecycle new group. group=0xc000091c08, appName=, streamName=notify_test - group__.go:185 -2026/04/23 10:56:11.868976  INFO [CUSTOMIZEPUB2] NewCustomizePubSessionContext. - customize_pubsession.go:42 -2026/04/23 10:56:11.868976 DEBUG [GROUP2] [CUSTOMIZEPUB2] add customize pub session into group. - group__in.go:33 -2026/04/23 10:56:11.868976  INFO create group, uniqueKey:, streamKey:notify_test - group.go:108 -2026/04/23 10:56:11.868976  INFO SetGroup, streamKey:notify_test - group_manager.go:105 -2026/04/23 10:56:11.868976  INFO AddSubscriber, streamKey:notify_test, subscriberId:consumer_notify, protocol:LALMAX - group.go:237 -2026/04/23 10:56:11.868976 ERROR http notify post error. err=Post "http://127.0.0.1:55559/on_update": dial tcp 127.0.0.1:55559: connectex: No connection could be made because the target machine actively refused it., url=http://127.0.0.1:55559/on_update, info={EventCommonInfo:{ServerId:} Groups:[]} - http_notify.go:216 -2026/04/23 10:56:14.869938  INFO http api start rtp pub. req info={StreamName:rtp_pub_test Port:0 TimeoutMs:0 IsTcpFlag:0 DebugDumpPacket:} - router.go:245 -2026/04/23 10:56:14.870245  INFO http api stop rtp pub. stream_name=rtp_pub_test, session_id= - router.go:271 diff --git a/server/router.go b/server/router.go index f941696..2210523 100644 --- a/server/router.go +++ b/server/router.go @@ -1,19 +1,6 @@ package server -import ( - "encoding/json" - "io" - "net/http" - - maxlogic "github.com/q191201771/lalmax/logic" - - "github.com/gin-gonic/gin" - "github.com/q191201771/lal/pkg/base" - "github.com/q191201771/lal/pkg/logic" - "github.com/q191201771/naza/pkg/nazahttp" - "github.com/q191201771/naza/pkg/nazajson" - "github.com/q191201771/naza/pkg/nazalog" -) +import "github.com/gin-gonic/gin" func (s *LalMaxServer) InitRouter(router *gin.Engine) { if router == nil { @@ -21,284 +8,10 @@ func (s *LalMaxServer) InitRouter(router *gin.Engine) { } router.Use(s.Cors()) - rtc := router.Group("/webrtc") - // whip - rtc.POST("/whip", s.HandleWHIP) - rtc.OPTIONS("/whip", s.HandleWHIP) - rtc.DELETE("/whip", s.HandleWHIP) - // whep - rtc.POST("/whep", s.HandleWHEP) - rtc.OPTIONS("/whep", s.HandleWHEP) - rtc.DELETE("/whep", s.HandleWHEP) - // Jessibuca flv封装play - rtc.POST("/play/live/:streamid", s.HandleJessibuca) - rtc.DELETE("/play/live/:streamid", s.HandleJessibuca) - - // http-fmp4 - router.GET("/live/m4s/:streamid", s.HandleHttpFmp4) - - // hls-fmp4/llhls - router.GET("/live/hls/:streamid/:type", s.HandleHls) + s.initRtcRouter(router) + s.initFmp4Router(router) auth := Authentication(s.conf.HttpConfig.CtrlAuthWhitelist.Secrets, s.conf.HttpConfig.CtrlAuthWhitelist.IPs) - // stat - stat := router.Group("/api/stat", auth) - stat.GET("/group", s.statGroupHandler) - stat.GET("/all_group", s.statAllGroupHandler) - stat.GET("/lal_info", s.statLalInfoHandler) - - // ctrl - ctrl := router.Group("/api/ctrl", auth) - ctrl.POST("/start_relay_pull", s.ctrlStartRelayPullHandler) - ctrl.POST("/stop_relay_pull", s.ctrlStopRelayPullHandler) - ctrl.POST("/kick_session", s.ctrlKickSessionHandler) - ctrl.POST("/start_rtp_pub", s.ctrlStartRtpPubHandler) - ctrl.POST("/stop_rtp_pub", s.ctrlStopRtpPubHandler) -} - -func (s *LalMaxServer) HandleWHIP(c *gin.Context) { - switch c.Request.Method { - case "POST": - if s.rtcsvr != nil { - s.rtcsvr.HandleWHIP(c) - } - case "DELETE": - // TODO 实现DELETE - c.Status(http.StatusOK) - } -} - -func (s *LalMaxServer) HandleWHEP(c *gin.Context) { - switch c.Request.Method { - case "POST": - if s.rtcsvr != nil { - s.rtcsvr.HandleWHEP(c) - } - case "DELETE": - // TODO 实现DELETE - c.Status(http.StatusOK) - } -} - -func (s *LalMaxServer) HandleJessibuca(c *gin.Context) { - switch c.Request.Method { - case "POST": - if s.rtcsvr != nil { - s.rtcsvr.HandleJessibuca(c) - } - case "DELETE": - // TODO 实现DELETE - c.Status(http.StatusOK) - } -} - -func (s *LalMaxServer) HandleHls(c *gin.Context) { - if s.hlssvr != nil { - s.hlssvr.HandleRequest(c) - } else { - nazalog.Error("hls is disable") - c.Status(http.StatusNotFound) - } -} - -func (s *LalMaxServer) HandleHttpFmp4(c *gin.Context) { - if s.httpfmp4svr != nil { - s.httpfmp4svr.HandleRequest(c) - } else { - nazalog.Error("http-fmp4 is disable") - c.Status(http.StatusNotFound) - } -} - -func (s *LalMaxServer) statGroupHandler(c *gin.Context) { - var v base.ApiStatGroupResp - streamName := c.Query("stream_name") - if streamName == "" { - v.ErrorCode = base.ErrorCodeParamMissing - v.Desp = base.DespParamMissing - c.JSON(http.StatusOK, v) - return - } - appName := c.Query("app_name") - v.Data = s.lalsvr.StatGroup(streamName) - if v.Data == nil { - v.ErrorCode = base.ErrorCodeGroupNotFound - v.Desp = base.DespGroupNotFound - c.JSON(http.StatusOK, v) - return - } - exist, session := maxlogic.GetGroupManagerInstance().GetGroup(maxlogic.NewStreamKey(appName, streamName)) - if exist { - v.Data.StatSubs = append(v.Data.StatSubs, session.StatSubscribers()...) - } - v.ErrorCode = base.ErrorCodeSucc - v.Desp = base.DespSucc - c.JSON(http.StatusOK, v) -} - -func (s *LalMaxServer) statAllGroupHandler(c *gin.Context) { - var out base.ApiStatAllGroupResp - out.ErrorCode = base.ErrorCodeSucc - out.Desp = base.DespSucc - groups := s.lalsvr.StatAllGroup() - for i, group := range groups { - exist, session := maxlogic.GetGroupManagerInstance().GetGroup(maxlogic.NewStreamKey(group.AppName, group.StreamName)) - if exist { - groups[i].StatSubs = append(groups[i].StatSubs, session.StatSubscribers()...) - } - } - out.Data.Groups = groups - c.JSON(http.StatusOK, out) -} - -func (s *LalMaxServer) statLalInfoHandler(c *gin.Context) { - var v base.ApiStatLalInfoResp - v.ErrorCode = base.ErrorCodeSucc - v.Desp = base.DespSucc - v.Data = s.lalsvr.StatLalInfo() - c.JSON(http.StatusOK, v) -} - -func (s *LalMaxServer) ctrlStartRelayPullHandler(c *gin.Context) { - var info base.ApiCtrlStartRelayPullReq - var v base.ApiCtrlStartRelayPullResp - j, err := unmarshalRequestJSONBody(c.Request, &info, "url") - if err != nil { - Log.Warnf("http api start pull error. err=%+v", err) - v.ErrorCode = base.ErrorCodeParamMissing - v.Desp = base.DespParamMissing - c.JSON(http.StatusOK, v) - return - } - - if !j.Exist("pull_timeout_ms") { - info.PullTimeoutMs = logic.DefaultApiCtrlStartRelayPullReqPullTimeoutMs - } - if !j.Exist("pull_retry_num") { - info.PullRetryNum = base.PullRetryNumNever - } - if !j.Exist("auto_stop_pull_after_no_out_ms") { - info.AutoStopPullAfterNoOutMs = base.AutoStopPullAfterNoOutMsNever - } - if !j.Exist("rtsp_mode") { - info.RtspMode = base.RtspModeTcp - } - - Log.Infof("http api start pull. req info=%+v", info) - - resp := s.lalsvr.CtrlStartRelayPull(info) - c.JSON(http.StatusOK, resp) -} - -func (s *LalMaxServer) ctrlStopRelayPullHandler(c *gin.Context) { - var v base.ApiCtrlStopRelayPullResp - streamName := c.Query("stream_name") - if streamName == "" { - v.ErrorCode = base.ErrorCodeParamMissing - v.Desp = base.DespParamMissing - c.JSON(http.StatusOK, v) - return - } - - Log.Infof("http api stop pull. stream_name=%s", streamName) - - resp := s.lalsvr.CtrlStopRelayPull(streamName) - c.JSON(http.StatusOK, resp) -} - -func (s *LalMaxServer) ctrlKickSessionHandler(c *gin.Context) { - var v base.ApiCtrlKickSessionResp - var info base.ApiCtrlKickSessionReq - - _, err := unmarshalRequestJSONBody(c.Request, &info, "stream_name", "session_id") - if err != nil { - Log.Warnf("http api kick session error. err=%+v", err) - v.ErrorCode = base.ErrorCodeParamMissing - v.Desp = base.DespParamMissing - c.JSON(http.StatusOK, v) - return - } - - Log.Infof("http api kick session. req info=%+v", info) - - resp := s.lalsvr.CtrlKickSession(info) - c.JSON(http.StatusOK, resp) -} - -func (s *LalMaxServer) ctrlStartRtpPubHandler(c *gin.Context) { - var v base.ApiCtrlStartRtpPubResp - var info base.ApiCtrlStartRtpPubReq - - j, err := unmarshalRequestJSONBody(c.Request, &info, "stream_name") - if err != nil { - Log.Warnf("http api start rtp pub error. err=%+v", err) - v.ErrorCode = base.ErrorCodeParamMissing - v.Desp = base.DespParamMissing - c.JSON(http.StatusOK, v) - return - } - - if !j.Exist("timeout_ms") { - info.TimeoutMs = logic.DefaultApiCtrlStartRtpPubReqTimeoutMs - } - - Log.Infof("http api start rtp pub. req info=%+v", info) - - resp := s.rtpPubMgr.Start(info) - c.JSON(http.StatusOK, resp) -} - -func (s *LalMaxServer) ctrlStopRtpPubHandler(c *gin.Context) { - var v base.ApiCtrlStopRelayPullResp - streamName := c.Query("stream_name") - sessionID := c.Query("session_id") - - if streamName == "" && sessionID == "" { - var info base.ApiCtrlKickSessionReq - if _, err := unmarshalRequestJSONBody(c.Request, &info); err == nil { - streamName = info.StreamName - sessionID = info.SessionId - } - } - - if streamName == "" && sessionID == "" { - v.ErrorCode = base.ErrorCodeParamMissing - v.Desp = base.DespParamMissing - c.JSON(http.StatusOK, v) - return - } - - Log.Infof("http api stop rtp pub. stream_name=%s, session_id=%s", streamName, sessionID) - - session, err := s.rtpPubMgr.Stop(streamName, sessionID) - if err != nil { - v.ErrorCode = base.ErrorCodeSessionNotFound - v.Desp = err.Error() - c.JSON(http.StatusOK, v) - return - } - - v.ErrorCode = base.ErrorCodeSucc - v.Desp = base.DespSucc - v.Data.SessionId = session.ID - c.JSON(http.StatusOK, v) -} - -func unmarshalRequestJSONBody(r *http.Request, info interface{}, keyFieldList ...string) (nazajson.Json, error) { - body, err := io.ReadAll(r.Body) - if err != nil { - return nazajson.Json{}, err - } - - j, err := nazajson.New(body) - if err != nil { - return j, err - } - for _, kf := range keyFieldList { - if !j.Exist(kf) { - return j, nazahttp.ErrParamMissing - } - } - - return j, json.Unmarshal(body, info) + s.initStatRouter(router, auth) + s.initCtrlRouter(router, auth) } diff --git a/server/router_ctrl.go b/server/router_ctrl.go new file mode 100644 index 0000000..e45572a --- /dev/null +++ b/server/router_ctrl.go @@ -0,0 +1,143 @@ +package server + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/q191201771/lal/pkg/base" + "github.com/q191201771/lal/pkg/logic" +) + +func (s *LalMaxServer) initCtrlRouter(router *gin.Engine, handlers ...gin.HandlerFunc) { + ctrl := router.Group("/api/ctrl", handlers...) + ctrl.POST("/start_relay_pull", s.ctrlStartRelayPullHandler) + ctrl.POST("/stop_relay_pull", s.ctrlStopRelayPullHandler) + ctrl.POST("/kick_session", s.ctrlKickSessionHandler) + ctrl.POST("/start_rtp_pub", s.ctrlStartRtpPubHandler) + ctrl.POST("/stop_rtp_pub", s.ctrlStopRtpPubHandler) +} + +func (s *LalMaxServer) ctrlStartRelayPullHandler(c *gin.Context) { + var info base.ApiCtrlStartRelayPullReq + var v base.ApiCtrlStartRelayPullResp + j, err := unmarshalRequestJSONBody(c.Request, &info, "url") + if err != nil { + Log.Warnf("http api start pull error. err=%+v", err) + v.ErrorCode = base.ErrorCodeParamMissing + v.Desp = base.DespParamMissing + c.JSON(http.StatusOK, v) + return + } + + if !j.Exist("pull_timeout_ms") { + info.PullTimeoutMs = logic.DefaultApiCtrlStartRelayPullReqPullTimeoutMs + } + if !j.Exist("pull_retry_num") { + info.PullRetryNum = base.PullRetryNumNever + } + if !j.Exist("auto_stop_pull_after_no_out_ms") { + info.AutoStopPullAfterNoOutMs = base.AutoStopPullAfterNoOutMsNever + } + if !j.Exist("rtsp_mode") { + info.RtspMode = base.RtspModeTcp + } + + Log.Infof("http api start pull. req info=%+v", info) + + resp := s.lalsvr.CtrlStartRelayPull(info) + c.JSON(http.StatusOK, resp) +} + +func (s *LalMaxServer) ctrlStopRelayPullHandler(c *gin.Context) { + var v base.ApiCtrlStopRelayPullResp + streamName := c.Query("stream_name") + if streamName == "" { + v.ErrorCode = base.ErrorCodeParamMissing + v.Desp = base.DespParamMissing + c.JSON(http.StatusOK, v) + return + } + + Log.Infof("http api stop pull. stream_name=%s", streamName) + + resp := s.lalsvr.CtrlStopRelayPull(streamName) + c.JSON(http.StatusOK, resp) +} + +func (s *LalMaxServer) ctrlKickSessionHandler(c *gin.Context) { + var v base.ApiCtrlKickSessionResp + var info base.ApiCtrlKickSessionReq + + _, err := unmarshalRequestJSONBody(c.Request, &info, "stream_name", "session_id") + if err != nil { + Log.Warnf("http api kick session error. err=%+v", err) + v.ErrorCode = base.ErrorCodeParamMissing + v.Desp = base.DespParamMissing + c.JSON(http.StatusOK, v) + return + } + + Log.Infof("http api kick session. req info=%+v", info) + + resp := s.lalsvr.CtrlKickSession(info) + c.JSON(http.StatusOK, resp) +} + +func (s *LalMaxServer) ctrlStartRtpPubHandler(c *gin.Context) { + var v base.ApiCtrlStartRtpPubResp + var info base.ApiCtrlStartRtpPubReq + + j, err := unmarshalRequestJSONBody(c.Request, &info, "stream_name") + if err != nil { + Log.Warnf("http api start rtp pub error. err=%+v", err) + v.ErrorCode = base.ErrorCodeParamMissing + v.Desp = base.DespParamMissing + c.JSON(http.StatusOK, v) + return + } + + if !j.Exist("timeout_ms") { + info.TimeoutMs = logic.DefaultApiCtrlStartRtpPubReqTimeoutMs + } + + Log.Infof("http api start rtp pub. req info=%+v", info) + + resp := s.rtpPubMgr.Start(info) + c.JSON(http.StatusOK, resp) +} + +func (s *LalMaxServer) ctrlStopRtpPubHandler(c *gin.Context) { + var v base.ApiCtrlStopRelayPullResp + streamName := c.Query("stream_name") + sessionID := c.Query("session_id") + + if streamName == "" && sessionID == "" { + var info base.ApiCtrlKickSessionReq + if _, err := unmarshalRequestJSONBody(c.Request, &info); err == nil { + streamName = info.StreamName + sessionID = info.SessionId + } + } + + if streamName == "" && sessionID == "" { + v.ErrorCode = base.ErrorCodeParamMissing + v.Desp = base.DespParamMissing + c.JSON(http.StatusOK, v) + return + } + + Log.Infof("http api stop rtp pub. stream_name=%s, session_id=%s", streamName, sessionID) + + session, err := s.rtpPubMgr.Stop(streamName, sessionID) + if err != nil { + v.ErrorCode = base.ErrorCodeSessionNotFound + v.Desp = err.Error() + c.JSON(http.StatusOK, v) + return + } + + v.ErrorCode = base.ErrorCodeSucc + v.Desp = base.DespSucc + v.Data.SessionId = session.ID + c.JSON(http.StatusOK, v) +} diff --git a/server/router_fmp4.go b/server/router_fmp4.go new file mode 100644 index 0000000..0b82c8e --- /dev/null +++ b/server/router_fmp4.go @@ -0,0 +1,31 @@ +package server + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/q191201771/naza/pkg/nazalog" +) + +func (s *LalMaxServer) initFmp4Router(router *gin.Engine) { + router.GET("/live/m4s/:streamid", s.HandleHttpFmp4) + router.GET("/live/hls/:streamid/:type", s.HandleHls) +} + +func (s *LalMaxServer) HandleHls(c *gin.Context) { + if s.hlssvr != nil { + s.hlssvr.HandleRequest(c) + } else { + nazalog.Error("hls is disable") + c.Status(http.StatusNotFound) + } +} + +func (s *LalMaxServer) HandleHttpFmp4(c *gin.Context) { + if s.httpfmp4svr != nil { + s.httpfmp4svr.HandleRequest(c) + } else { + nazalog.Error("http-fmp4 is disable") + c.Status(http.StatusNotFound) + } +} diff --git a/server/router_helper.go b/server/router_helper.go new file mode 100644 index 0000000..d4fc27b --- /dev/null +++ b/server/router_helper.go @@ -0,0 +1,29 @@ +package server + +import ( + "encoding/json" + "io" + "net/http" + + "github.com/q191201771/naza/pkg/nazahttp" + "github.com/q191201771/naza/pkg/nazajson" +) + +func unmarshalRequestJSONBody(r *http.Request, info interface{}, keyFieldList ...string) (nazajson.Json, error) { + body, err := io.ReadAll(r.Body) + if err != nil { + return nazajson.Json{}, err + } + + j, err := nazajson.New(body) + if err != nil { + return j, err + } + for _, kf := range keyFieldList { + if !j.Exist(kf) { + return j, nazahttp.ErrParamMissing + } + } + + return j, json.Unmarshal(body, info) +} diff --git a/server/router_rtc.go b/server/router_rtc.go new file mode 100644 index 0000000..bfb0fc1 --- /dev/null +++ b/server/router_rtc.go @@ -0,0 +1,57 @@ +package server + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func (s *LalMaxServer) initRtcRouter(router *gin.Engine) { + rtc := router.Group("/webrtc") + rtc.POST("/whip", s.HandleWHIP) + rtc.OPTIONS("/whip", s.HandleWHIP) + rtc.DELETE("/whip", s.HandleWHIP) + + rtc.POST("/whep", s.HandleWHEP) + rtc.OPTIONS("/whep", s.HandleWHEP) + rtc.DELETE("/whep", s.HandleWHEP) + + rtc.POST("/play/live/:streamid", s.HandleJessibuca) + rtc.DELETE("/play/live/:streamid", s.HandleJessibuca) +} + +func (s *LalMaxServer) HandleWHIP(c *gin.Context) { + switch c.Request.Method { + case "POST": + if s.rtcsvr != nil { + s.rtcsvr.HandleWHIP(c) + } + case "DELETE": + // TODO 实现 DELETE + c.Status(http.StatusOK) + } +} + +func (s *LalMaxServer) HandleWHEP(c *gin.Context) { + switch c.Request.Method { + case "POST": + if s.rtcsvr != nil { + s.rtcsvr.HandleWHEP(c) + } + case "DELETE": + // TODO 实现 DELETE + c.Status(http.StatusOK) + } +} + +func (s *LalMaxServer) HandleJessibuca(c *gin.Context) { + switch c.Request.Method { + case "POST": + if s.rtcsvr != nil { + s.rtcsvr.HandleJessibuca(c) + } + case "DELETE": + // TODO 实现 DELETE + c.Status(http.StatusOK) + } +} diff --git a/server/router_stat.go b/server/router_stat.go new file mode 100644 index 0000000..cda5640 --- /dev/null +++ b/server/router_stat.go @@ -0,0 +1,65 @@ +package server + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/q191201771/lal/pkg/base" + maxlogic "github.com/q191201771/lalmax/logic" +) + +func (s *LalMaxServer) initStatRouter(router *gin.Engine, handlers ...gin.HandlerFunc) { + stat := router.Group("/api/stat", handlers...) + stat.GET("/group", s.statGroupHandler) + stat.GET("/all_group", s.statAllGroupHandler) + stat.GET("/lal_info", s.statLalInfoHandler) +} + +func (s *LalMaxServer) statGroupHandler(c *gin.Context) { + var v base.ApiStatGroupResp + streamName := c.Query("stream_name") + if streamName == "" { + v.ErrorCode = base.ErrorCodeParamMissing + v.Desp = base.DespParamMissing + c.JSON(http.StatusOK, v) + return + } + appName := c.Query("app_name") + v.Data = s.lalsvr.StatGroup(streamName) + if v.Data == nil { + v.ErrorCode = base.ErrorCodeGroupNotFound + v.Desp = base.DespGroupNotFound + c.JSON(http.StatusOK, v) + return + } + exist, session := maxlogic.GetGroupManagerInstance().GetGroup(maxlogic.NewStreamKey(appName, streamName)) + if exist { + v.Data.StatSubs = append(v.Data.StatSubs, session.StatSubscribers()...) + } + v.ErrorCode = base.ErrorCodeSucc + v.Desp = base.DespSucc + c.JSON(http.StatusOK, v) +} + +func (s *LalMaxServer) statAllGroupHandler(c *gin.Context) { + var out base.ApiStatAllGroupResp + out.ErrorCode = base.ErrorCodeSucc + out.Desp = base.DespSucc + groups := s.lalsvr.StatAllGroup() + for i, group := range groups { + exist, session := maxlogic.GetGroupManagerInstance().GetGroup(maxlogic.NewStreamKey(group.AppName, group.StreamName)) + if exist { + groups[i].StatSubs = append(groups[i].StatSubs, session.StatSubscribers()...) + } + } + out.Data.Groups = groups + c.JSON(http.StatusOK, out) +} + +func (s *LalMaxServer) statLalInfoHandler(c *gin.Context) { + var v base.ApiStatLalInfoResp + v.ErrorCode = base.ErrorCodeSucc + v.Desp = base.DespSucc + v.Data = s.lalsvr.StatLalInfo() + c.JSON(http.StatusOK, v) +}