2015-06-27 11 views
3

Чтобы отладить проблему задержки брандмауэра, мне нужно приложение, которое будет генерировать звуковой сигнал на стороне сервера, когда он обнаружит запрос HTTP GET.Beep в приложении C# .NET на стороне сервера

Этот код (test.ashx):

<%@ WebHandler Language="C#" Class="TestHandler" %> 

using System; 
using System.Web; 

public class TestHandler : IHttpHandler 
{ 
    public void ProcessRequest(HttpContext context) 
    { 
     HttpResponse Response = context.Response; 
     try 
     { 
      Response.Write("Before beep"); 
      Console.Beep(); 
      Response.Write("After beep"); 
     } 
     catch (Exception ex) 
     { 
      Response.Write(ex.Message + "<br />\n" + ex.InnerException.Message); 
     } 
    } 

    public bool IsReusable { get { return false; } } 
} 

производит звук только при отладке в IIS Express. После перемещения веб-приложения в IIS звук исчезает.

+0

Простой тест первый: Откройте окна DOS, введите команду эхо _ [Ctrl_G] _ (нажав Ctrl и G) и слушать, если звучит звук. – Graffito

+0

Рассматривали ли вы добавление правильного ведения журнала? Один из вариантов - log4net https://www.nuget.org/packages/log4net/ - крутая кривая обучения, но стоит того –

ответ

6

Три простых способа получения звука являются System.Console.Beep(), System.Media.SoundPlayer и System.Media.SystemSounds.Beep().

К сожалению, эти методы работают только в настольных приложениях и не будут работать в служебных приложениях. Когда приложения ASP.Net работают под управлением IIS Express (настольное приложение), эти звуковые методы работают. Однако, когда приложения ASP.Net запускаются под службой IIS, звуковые методы не работают.

System.Console.Beep() в конечном итоге вызывает функцию kernel32.dll Beep(). Он ограничен только для настольных приложений (прокрутите вниз до раздела «Требования»).

То же самое для System.Media.SoundPlayer и System.Media.SystemSounds.Beep(). Они называют kernel32.dll MessageBeep() и функциями winmm.dll PlaySound(), соответственно. Они также ограничены настольными приложениями.

Один из способов получить звуки для воспроизведения в службе - NAudio. Его легко установить через NuGet.

Этот кусок кода - единственный способ заставить звук играть. Он должен воспроизводиться на отдельном рабочем потоке, и выполнение рабочего потока должно быть приостановлено, чтобы файл WAV закончил игру.

using System; 
using System.Diagnostics; 
using System.Threading; 

using NAudio.Dsp; 
using NAudio.Wave; 

... 

protected void Button1_Click(object sender, EventArgs e) 
{ 
    var waveFilename = @"c:\Windows\Media\tada.wav"; 

    /* Trying to play the .wav file on the main thread 
    doesn't seem to work. */ 
    ThreadPool.QueueUserWorkItem(
    (state) => 
    { 
     using (var audioPlayback = new AudioPlayback()) 
     { 
     audioPlayback.Load(waveFilename); 
     audioPlayback.Play(); // Asynchronous. 

     /* Need to sleep for the approximate length of .wav file, 
      otherwise no sound is produced because of the 
      asynchronous Play() call. */ 
     Thread.Sleep(2000); 
     } 
    }); 
} 

Вот опорный код взят из кода в проекте NAudioWPFDemo NAudio в:

public class MaxSampleEventArgs : EventArgs 
{ 
    [DebuggerStepThrough] 
    public MaxSampleEventArgs(float minValue, float maxValue) 
    { 
    this.MaxSample = maxValue; 
    this.MinSample = minValue; 
    } 
    public float MaxSample { get; private set; } 
    public float MinSample { get; private set; } 
} 

public class FftEventArgs : EventArgs 
{ 
    [DebuggerStepThrough] 
    public FftEventArgs(Complex[] result) 
    { 
    this.Result = result; 
    } 
    public Complex[] Result { get; private set; } 
} 

public class SampleAggregator : ISampleProvider 
{ 
    // volume 
    public event EventHandler<MaxSampleEventArgs> MaximumCalculated; 
    private float maxValue; 
    private float minValue; 
    public int NotificationCount { get; set; } 
    int count; 

    // FFT 
    public event EventHandler<FftEventArgs> FftCalculated; 
    public bool PerformFFT { get; set; } 
    private readonly Complex[] fftBuffer; 
    private readonly FftEventArgs fftArgs; 
    private int fftPos; 
    private readonly int fftLength; 
    private int m; 
    private readonly ISampleProvider source; 

    private readonly int channels; 

    public SampleAggregator(ISampleProvider source, int fftLength = 1024) 
    { 
    channels = source.WaveFormat.Channels; 
    if (!IsPowerOfTwo(fftLength)) 
     throw new ArgumentException("FFT Length must be a power of two"); 

    this.m = (int) Math.Log(fftLength, 2.0); 
    this.fftLength = fftLength; 
    this.fftBuffer = new Complex[fftLength]; 
    this.fftArgs = new FftEventArgs(fftBuffer); 
    this.source = source; 
    } 

    private bool IsPowerOfTwo(int x) 
    { 
    return (x & (x - 1)) == 0; 
    } 

    public void Reset() 
    { 
    count = 0; 
    maxValue = minValue = 0; 
    } 

    private void Add(float value) 
    { 
    if (PerformFFT && FftCalculated != null) 
    { 
     fftBuffer[fftPos].X = (float) (value * FastFourierTransform.HammingWindow(fftPos, fftLength)); 
     fftBuffer[fftPos].Y = 0; 
     fftPos++; 
     if (fftPos >= fftBuffer.Length) 
     { 
     fftPos = 0; 
     // 1024 = 2^10 
     FastFourierTransform.FFT(true, m, fftBuffer); 
     FftCalculated(this, fftArgs); 
     } 
    } 

    maxValue = Math.Max(maxValue, value); 
    minValue = Math.Min(minValue, value); 
    count++; 
    if (count >= NotificationCount && NotificationCount > 0) 
    { 
     if (MaximumCalculated != null) 
     MaximumCalculated(this, new MaxSampleEventArgs(minValue, maxValue)); 

     Reset(); 
    } 
    } 

    public WaveFormat WaveFormat { get { return source.WaveFormat; } } 

    public int Read(float[] buffer, int offset, int count) 
    { 
    var samplesRead = source.Read(buffer, offset, count); 

    for (int n = 0; n < samplesRead; n += channels) 
     Add(buffer[n + offset]); 

    return samplesRead; 
    } 
} 

public class AudioPlayback : IDisposable 
{ 
    private IWavePlayer _playbackDevice; 
    private WaveStream _fileStream; 

    public void Load(string fileName) 
    { 
    Stop(); 
    CloseFile(); 
    EnsureDeviceCreated(); 
    OpenFile(fileName); 
    } 

    private void CloseFile() 
    { 
    if (_fileStream != null) 
    { 
     _fileStream.Dispose(); 
     _fileStream = null; 
    } 
    } 

    private void OpenFile(string fileName) 
    { 
    try 
    { 
     var inputStream = new AudioFileReader(fileName); 
     _fileStream = inputStream; 
     var aggregator = new SampleAggregator(inputStream); 
     aggregator.NotificationCount = inputStream.WaveFormat.SampleRate/100; 
     aggregator.PerformFFT = true; 
     _playbackDevice.Init(aggregator); 
    } 
    catch 
    { 
     CloseFile(); 
     throw; 
    } 
    } 

    private void EnsureDeviceCreated() 
    { 
    if (_playbackDevice == null) 
     CreateDevice(); 
    } 

    private void CreateDevice() 
    { 
    _playbackDevice = new WaveOut { DesiredLatency = 200 }; 
    } 

    public void Play() 
    { 
    if (_playbackDevice != null && _fileStream != null && _playbackDevice.PlaybackState != PlaybackState.Playing) 
     _playbackDevice.Play(); 
    } 

    public void Pause() 
    { 
    if (_playbackDevice != null) 
     _playbackDevice.Pause(); 
    } 

    public void Stop() 
    { 
    if (_playbackDevice != null) 
     _playbackDevice.Stop(); 

    if (_fileStream != null) 
     _fileStream.Position = 0; 
    } 

    public void Dispose() 
    { 
    Stop(); 
    CloseFile(); 
    if (_playbackDevice != null) 
     _playbackDevice.Dispose(); 
    } 
} 
+1

+1 Очень приятно, что вы нашли время, чтобы объяснить, почему обычные способы не работают, и альтернативное решение. –

+0

Проверенный. Оно работает!. Большое спасибо. – Paul

-1

Попробуйте это System.Media.SystemSounds.Beep.Play();

 Смежные вопросы

  • Нет связанных вопросов^_^