Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.3k views
in Technique[技术] by (71.8m points)

c# - Closing HttpListener is failing

I have a WPF app which contains MediaElement to play video and it also runs the HttpServer which returns the response of the video file as an array of bytes. The HttpServer runs on localhost:1234 and MediaElement.source points to localhost:1234. The app plays the video, however it fails to re-play if I re-open the file to play the same or another one again without prior closing of the app. The error is obvious: the httplistener on 1234 port is occupied. So the best option would be to close the listener and reopen it again. However it does not work. Any ideas how to properly close the listener?

Another interesting moment here is that the file gets read and returned 2 times instead of 1, not sure why. But if I replace while cycle to for(int i=0; i<2; i++) then it does not work at all.

Here's the code:

string videoServerUrl = "http://localhost:1234/";
public HttpListener listener;

public async Task HandleIncomingConnections(string fileName)
{
    bool runServer = true;
    
    while (runServer)             
    {
        HttpListenerContext ctx = await listener.GetContextAsync();

        HttpListenerRequest req = ctx.Request;
        HttpListenerResponse resp = ctx.Response;

        if (req.HttpMethod == "POST")  
        {
            runServer = false;
            resp.Close();
            return;
        }

        var bytesRead = File.ReadAllBytes(fileName);
        resp.ContentLength64 = bytesRead.Length;
        await resp.OutputStream.WriteAsync(bytesRead, 0, bytesRead.Length);

        resp.Close();
    }
}

private void RunServer(string fileName)
{
     listener = new HttpListener();
     listener.Prefixes.Add(videoServerUrl);
     listener.Start();
         
     Task listenTask = HandleIncomingConnections(fileName);
     listenTask.GetAwaiter().GetResult();

     listener.Close();     
}


private async void Button_Click(object sender, RoutedEventArgs e)
{
    try
    {    
        OpenFileDialog openFileDialog = new OpenFileDialog();
        if (openFileDialog.ShowDialog() == true)
        {                    
            string videoFileName = openFileDialog.FileName;
            player.LoadedBehavior = MediaState.Manual;
            player.Source = new Uri(videoServerUrl.ToString(), UriKind.RelativeOrAbsolute);
            player.Play();

            Task.Run(() => RunServer(videoFileName)).ConfigureAwait(false);
       
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...