2015-06-27 47 views
3

要調試防火牆延遲問題,我需要一個應用程序,它會在檢測到HTTP GET請求時在服務器端產生嘟嘟聲。在服務器端的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進行調試只有當。將Web應用程序移至IIS後,聲音消失。

+0

一個簡單的測試第一:打開DOS窗口,_ [CTRL_G] _(按Ctrl鍵入命令回聲和G鍵)並監聽是否產生了聲音。 – Graffito

+0

你有沒有考慮添加正確的日誌記錄?一個選項是log4net https://www.nuget.org/packages/log4net/ - 陡峭的學習曲線,但非常值得 –

回答

6

三個簡單的方法是System.Console.Beep()System.Media.SoundPlayerSystem.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); 
     } 
    }); 
} 

下面是來自代碼在n音訊的NAudioWPFDemo項目採取的支持代碼:

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();