记录一次IIS部署webform请求调用python服务的异常处理

Posted 丁小未

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录一次IIS部署webform请求调用python服务的异常处理相关的知识,希望对你有一定的参考价值。

需求

需要做一个获取视频网站的后台服务接口,输入一个房间号,获取对应的直播URL,然后给客户端展示直播。

分析

  • 执行对应的python逻辑,输入房间号,返回直播URL
  • 创建对应的webform一般处理程序服务,需要用到C#执行python
  • 发布IIS,这里需要避免权限问题的坑

对应代码

Python

# 获取哔哩哔哩直播的真实流媒体地址,默认获取直播间提供的最高画质
# qn=150高清
# qn=250超清
# qn=400蓝光
# qn=10000原画
import requests

import argparse
parser = argparse.ArgumentParser(description='manual to this script')
parser.add_argument("--roomId", type=str, default="2171135", help='search roomId')
args = parser.parse_args()

class BiliBili:

    def __init__(self, rid):
        """
        有些地址无法在PotPlayer播放,建议换个播放器试试
        Args:
            rid:
        """
        rid = rid
        self.header = 
            'User-Agent': 'Mozilla/5.0 (iPod; CPU iPhone OS 14_5 like Mac OS X) AppleWebKit/605.1.15 (Khtml, '
                          'like Gecko) Crios/87.0.4280.163 Mobile/15E148 Safari/604.1',
        
        # 先获取直播状态和真实房间号
        r_url = 'https://api.live.bilibili.com/room/v1/Room/room_init'
        param = 
            'id': rid
        
        with requests.Session() as self.s:
            res = self.s.get(r_url, headers=self.header, params=param).json()
        if res['msg'] == '直播间不存在':
            raise Exception(f'bilibili rid res["msg"]')
        live_status = res['data']['live_status']
        if live_status != 1:
            raise Exception(f'bilibili rid 未开播')
        self.real_room_id = res['data']['room_id']

    def get_real_url(self, current_qn: int = 10000) -> dict:
        url = 'https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo'
        param = 
            'room_id': self.real_room_id,
            'protocol': '0,1',
            'format': '0,1,2',
            'codec': '0,1',
            'qn': current_qn,
            'platform': 'h5',
            'ptype': 8,
        
        res = self.s.get(url, headers=self.header, params=param).json()
        stream_info = res['data']['playurl_info']['playurl']['stream']
        qn_max = 0

        for data in stream_info:
            accept_qn = data['format'][0]['codec'][0]['accept_qn']
            for qn in accept_qn:
                qn_max = qn if qn > qn_max else qn_max
        if qn_max != current_qn:
            param['qn'] = qn_max
            res = self.s.get(url, headers=self.header, params=param).json()
            stream_info = res['data']['playurl_info']['playurl']['stream']

        stream_urls = 
        # flv流无法播放,暂修改成获取hls格式的流,
        for data in stream_info:
            format_name = data['format'][0]['format_name']
            if format_name == 'ts':
                base_url = data['format'][-1]['codec'][0]['base_url']
                url_info = data['format'][-1]['codec'][0]['url_info']
                for i, info in enumerate(url_info):
                    host = info['host']
                    extra = info['extra']
                    stream_urls[f'线路i + 1'] = f'hostbase_urlextra'
                break
        return stream_urls


def get_real_url(rid):
    try:
        bilibili = BiliBili(rid)
        return bilibili.get_real_url()
    except Exception as e:
        print('Exception:', e)
        return False


if __name__ == '__main__':
    #r = input('请输入bilibili直播房间号:\\n')
    print(args.roomId)
    print(get_real_url(args.roomId))

C#一般处理程序

using System;
using System.IO;
using System.Web;

namespace MonitorToolSystem

    /// <summary>
    /// GetBrocastLiveUrl 的摘要说明
    /// </summary>
    public class GetBrocastLiveUrl : IHttpHandler
    
        public void ProcessRequest(HttpContext context)
        
            context.Response.ContentType = "text/plain";
            var roomId = context.Request["roomId"];
            //服务器跟PC的python地址
            string pyToolPath = @"C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python39\\python.exe"; //c:\\users\\d00605132\\appdata\\local\\programs\\python\\python39\\python.exe
            //string pyToolPath = @"c:\\users\\d00605132\\appdata\\local\\programs\\python\\python39\\python.exe";
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Pythons/bilibiliModify.py"); ;//(因为我没放debug下,所以直接写的绝对路径,替换掉上面的路径了)
            string sArguments = path;
            if (!string.IsNullOrEmpty(roomId))
            
                sArguments = sArguments + $" --roomId=roomId";
            
            p.StartInfo.FileName = pyToolPath;
            p.StartInfo.UseShellExecute = true;
            p.StartInfo.Arguments = sArguments;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = false;
            p.Start();
            while (!p.HasExited)
            
                p.WaitForExit();
            
            string output = p.StandardOutput.ReadToEnd();
            if (string.IsNullOrEmpty(output))
            
                context.Response.Write($"error:沒有查询到房间数据");
            
            else
            
                context.Response.Write($"output");
            
        

        public bool IsReusable
        
            get
            
                return false;
            
        
    

这里Python版本是3.9.6

IIS设置避坑

本地跑的好好的,但一旦发布IIS,就会碰到访问权限的问题,会报错System.ComponentModel.Win32Exception拒绝访问,首先IIS需要以管理员身份运行,其次在Web.config中配置管理员账户访问权限,在<system.web>中配置

<identity impersonate="true" userName="Administrator" password="xxx"/>

然后发现不报访问权限的错了,但是process没有返回值,这就很蛋疼,前面用户权限的问题坑了我一晚上,在公司处理到11点还没搞定失望而归,今天又在公司白天解决了访问权限的问题,但却没有正确得到返回值,又是解决问题,后来发现应用程序池需要设置标识为LocalSystem,非常重要,然后就能正确运行了
http://116.205.247.142:8080/GetBrocastLiveUrl.ashx?roomId=2171135

上图是房间号为2171135的直播间的直播线路地址,如果当前房间没有直播,就是返回一下值

结论

有以上经验,我就能做一个直播平台的聚合app了,只要知道各个平台的房间号,就能做一个根据直播类型分类的超大聚合直播app,是不是很开心呢!

以上是关于记录一次IIS部署webform请求调用python服务的异常处理的主要内容,如果未能解决你的问题,请参考以下文章

记录一次IIS部署webform请求调用python服务的异常处理

WebForm的Global.asax文件

IIS WebForm开发基础

在 iis 中部署 asp.net webforms 我根本没有 Css 样式

WebApi 部署IIS 404.0 not found

求asp.net webform 工作的流程